php - 逐行读取文件的更快方法?

标签 php mysql fgets

在 PHP 中,我使用 fopen( )fgets( )fclose( ) 逐行读取文件。它运作良好。但是我有一个脚本(从 CLI 运行)必须处理三百个 5GB 的文本文件。这大约是 30 亿个 fgets( )。所以它工作得很好,但在这种规模下,微小的速度节省将以极快的速度累积起来。所以我想知道是否有任何技巧可以加快这个过程?

我想到的唯一可能的事情是让 fgets( ) 一次读取多行。它看起来并不支持,但理论上我可以说 20 个连续的 $line[] = fgets($file); 然后处理数组。这与在一个命令中读取多行并不完全相同,因此它可能没有任何影响。但我知道将您的 mysql 插入排队并将它们作为一个巨大的插入发送(我将在更多测试和基准测试后在此脚本中实现的另一个技巧)将节省大量时间。

2019 年 4 月 13 日更新 这是我使用的解决方案。最初我有一个更复杂的方法来切掉每次阅读的结尾,但后来我意识到你可以做得更简单。

$index_file = fopen( path to file,"r" );
$chunk = "";
while ( !feof($index_file) )
    {
    $chunk .= fread($index_file,$read_length);
    $payload_lines = explode("\n",$chunk);

    if ( !feof($index_file) )
        { $chunk = array_pop($payload_lines); }

    }

当然,PHP 具有适用于一切的函数。因此,我将每次读取都分解为一个行数组,并将数组中的最后一项 array_pop() 返回到“读取缓冲区”的开头。最后一部分可能是 split 的,但不一定是 split 的。但无论哪种方式,它都会返回并在下一个循环中进行处理(除非我们处理完文件,否则我们不会弹出它)。

在这里您唯一需要注意的是,如果您的一行太长以至于单次读取无法捕获全部内容。但是了解您的数据,这可能不会很麻烦。对我来说,我正在解析一个 json-ish 文件,我一次读取 128 KB,所以在我的读取中总是有很多换行符。

注意:我通过进行一百万次基准测试并发现我的服务器处理速度绝对最快,最终确定为 128 KB。此解析函数将运行 300 次,因此我每节省一秒,总运行时间就会节省 5 分钟。

最佳答案

一种可能更快的方法是使用 fread() 读取文件的大块,用换行符拆分它,然后处理这些行。您必须考虑到这些 block 可能会切断线条,您必须检测到这一点并将它们粘在一起。

一般来说,您一次可以读取的数据 block 越大,您的进程就应该变得越快。在可用内存的限制内。

来自 fread() docs :

Note that fread() reads from the current position of the file pointer. Use ftell() to find the current position of the pointer and rewind() to rewind the pointer position.

关于php - 逐行读取文件的更快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44281401/

相关文章:

c - 从文件中读取带空格的字符串

c - C语言获取多个单词不获取\n

php - 直接从 jQuery 插件发出 Ajax 请求是不好的做法吗?

mysql - 获取mysql字段的总和并传递总和以在codeigniter中查看

c - stdin 的 fscanf 不提示输入

mysql - 来自 hasmany 关系值的 Laravel 子查询值

php - Laravel 5.4 Passport-API 无法设置 30 天过期 token

javascript - YIi应用程序的可扩展性和并发性

php - MySQL 查询选择两个用户之间的冲突计数

javascript - Ajax 到 Laravel 返回 404 并且 Responsejson 未定义