PHP 读取大文件1T硬盘, 800G IP文件 找出IP出现最多的前10个 fopen yield生成器 分割读取 二进制读取

    xiaoxiao2022-07-14  192

    PHP 读取大文件 1T硬盘 , 800G IP文件 找出IP出现最多的前10个 文件操作操作文件流 PHP 流操作 操作

    原题是 2核的CPU 1T的硬盘 现有800G的IP文件 取出IP出现次数最多的前10 个 第一印象想到的就是PHP 的生成器 yield 批量去读取文件 然后说的不是很好, 技术面试我的, 然后 他叹了口气 ,让我回去等通知( 哈哈 ) 肯定是凉了, 但是他那个叹气 现在想起来就 想笑 回归正题 因为PHP是弱语言 ,一次性读取这么大 受不了, 换成 别的语言肯定也受不了 , 利用生成器(关键字yield)就能解决 参数介绍 yield 生成器 必须在方法里面使用 fopen 获取文件 feof() 函数检测是否已到达文件末尾 (eof)。 fgetcsv()函数从文件指针中读入一行并解析 函数会在到达指定长度或读到文件末尾 fgets 函数从文件指针中读取一行。 第二参数 函数从文件指针中读取一行。

    function read_file(){ $f = fopen("txt.txt",'r'); //rb 读写打开一个二进制文件 while (feof($f)==false) { yield fgets($f); //函数从文件指针中读取一行。 } fclose($f); } $file = read_file();

    用函数 查看一下当前峰值内存 函数

    function formatBytes($bytes, $precision = 2) { $units = array("b", "kb", "mb", "gb", "tb"); $bytes = max($bytes, 0); $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= (1 << (10 * $pow)); //round() 函数对浮点数进行四舍五入。 return round($bytes, $precision) . " " . $units[$pow]; } echo formatBytes(memory_get_peak_usage());

    如果是用 变量接内容峰值会很大 会发现 比正常赋值 的峰值内存 小超级多 峰值 内存1.47 Mb 文件内存 575KB 可以看到内存会小很多 用PHP 的生成器 + 文件切割读取 一共有1T 硬盘 800G 目前还有 180G左右的内存空间 可以把 文件 分割成8次读取 每次读取进行排序 取出前10名的,叠加保存到临时文件中 以此类推, 等8次全部读取完毕之后, 打开临时文件 再次进行排序 找出前10个 就完成了 基本就是这个思路

    最新回复(0)