2017-05-31 47 views
1

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

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

+0

你可以尝试读取它“缓冲区缓冲区”,并再次分开线路 – modsfabio

+0

你尝试使用fgetcsv函数吗? –

+0

对于php脚本的mmap或createfilemapping会有帮助https://github.com/calcinai/php-mmap – tommybee

回答

0

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

一般而言,您可以一次读取的块越大,您的过程应该变得越快。在可用内存的范围内。

fread() docs来自:

注意FREAD()从文件指针的当前位置的读取。使用ftell()来查找指针的当前位置,并使用rewind()来倒回指针位置。

+0

我将如何处理分割线?我想我可以保存在后面最后一个'换行'之后出现的任何内容,并将它粘贴到下一次阅读的开头。你怎么知道fread()从哪里读取?或者像fgets一样,当你不断地调用它时,它是否会自动通过文件自动递增? – l008com

+0

@ l008com是的。你需要一些变量来存储在最后一个换行符后面出现的任何变量,并将它与下一个块中第一个换行符之前的内容组合起来。 – Kempeth