考虑到我有一个包含数百万行文本的100GB txt文件。我怎么能用PHP的行块读取这个文本文件?
我无法使用file_get_contents();
因为文件太大。 fgets()
也逐行阅读文本,这可能需要更长的时间才能完成阅读整个文件。
如果我将使用fread($fp,5030)
,其中'5030'是必须读取的某个长度值。是否会出现因为已达到最大长度而无法读取整行(例如在行中间停止)的情况?
答案 0 :(得分:4)
我不能使用file_get_contents();因为文件太大了。 fgets()也逐行读取文本,这可能需要更长的时间才能完成阅读整个文件。
不明白,为什么你不能使用fgets()
$blocksize = 50; // in "number of lines"
while (!feof($fh)) {
$lines = array();
$count = 0;
while (!feof($fh) && (++$count <= $blocksize)) {
$lines[] = fgets($fh);
}
doSomethingWithLines($lines);
}
无论如何,阅读100GB都需要时间。
答案 1 :(得分:1)
fread
方法听起来像是一个合理的解决方案。您可以通过检查字符串中的最后一个字符是否为换行符('\n'
)来检测您是否已到达行尾。如果不是,那么您可以阅读更多字符并将它们附加到现有字符串,或者您可以将字符串中的字符修剪回上一个换行符,然后使用fseek
调整您的位置。文件。
侧点:您是否知道读取100GB文件需要非常很长时间?
答案 2 :(得分:1)
我认为你必须使用fread($ fp,somesize),并且如果你已经创建了行的末尾则手动检查,否则读取另一个块。
希望这有帮助。
答案 3 :(得分:1)
我建议在函数中实现单行读取,从其余代码中隐藏该特定步骤的实现细节 - 处理函数不必关心如何检索行。然后,您可以使用fgets()
实现您的第一个版本,然后尝试其他方法如果您发现它太慢了。很可能初始实施太慢了,但重点是:在基准测试之前你不会知道。
答案 4 :(得分:0)
我知道这是一个老问题,但我认为最终找到这个问题的任何人都有新的答案值。
我同意阅读100GB需要时间,我也同意我为什么需要找到最有效的选项来阅读它所以它可以尽可能少而不只是想“谁在乎它是多少如果是已经很多了“,所以,让我们找出可能的最短时间。
使用fread读取该数据的缓存
从缓存中逐行读取,直到缓存结束或找到数据结束
抓取未处理的块的最后一部分(您正在寻找行分隔符的那一部分)并在前面移动它,然后读取您定义的大小的块减去未处理数据的大小并将其放入在那个未经处理的块之后,那么,你去了,你有一个新的完整块 重复读取行和此过程,直到完全读取文件。
您应该使用大于任何预期行数的缓存块。
缓存大小越大,读取的速度越快,但使用的内存越多。