使用php读取文件中的行块

使用php读取文件中的行块,php,file,fgets,fread,Php,File,Fgets,Fread,考虑到我有一个100GB的txt文件,其中包含数百万行文本。如何使用PHP逐行读取此文本文件 我不能使用文件获取内容()因为文件太大fgets()还要逐行读取文本,这可能需要更长的时间来完成整个文件的读取 如果我将使用fread($fp,5030)其中'5030'是它必须读取的某个长度值。是否会出现这样的情况,即它不会读取整行数据(例如在行的中间停止),因为它已达到最大长度?fread方法听起来是一个合理的解决方案。您可以通过检查字符串中的最后一个字符是否为换行符('\n')来检测是否已到达行尾

考虑到我有一个100GB的txt文件,其中包含数百万行文本。如何使用PHP逐行读取此文本文件

我不能使用
文件获取内容()因为文件太大
fgets()
还要逐行读取文本,这可能需要更长的时间来完成整个文件的读取


如果我将使用
fread($fp,5030)
其中'5030'是它必须读取的某个长度值。是否会出现这样的情况,即它不会读取整行数据(例如在行的中间停止),因为它已达到最大长度?

fread
方法听起来是一个合理的解决方案。您可以通过检查字符串中的最后一个字符是否为换行符(
'\n'
)来检测是否已到达行尾。如果不是,则可以读取更多字符并将其附加到现有字符串中,或者可以将字符串中的字符修剪回最后一个换行符,然后使用
fseek
调整您在文件中的位置


侧重点:您知道读取100GB文件需要很长时间吗?

我认为您必须使用fread($fp,somesize),并手动检查是否找到了行的结尾,否则读取另一个块


希望这能有所帮助。

我建议在函数中实现一行的读取,对代码的其余部分隐藏该特定步骤的实现细节-处理函数不能关心如何检索该行。然后,您可以使用
fgets()
实现第一个版本,如果发现速度太慢,可以尝试其他方法。很可能是最初的实现太慢了,但关键是:在进行基准测试之前,您不会知道

我无法使用文件获取内容();因为文件太大了。fgets()还逐行读取文本,这可能需要更长的时间才能完成整个文件的读取

不明白,为什么不能使用
fgets()

$blocksize=50;//在“行数”中
而(!feof($fh)){
$lines=array();
$count=0;

虽然(!feof($fh)&(++$count我知道这是一个老问题,但我认为对于最终找到这个问题的任何人来说,新答案都是有价值的

我同意阅读100GB需要时间,这就是为什么我也同意我们需要找到最有效的方法来阅读它,这样它就可以尽可能少,而不是仅仅想“如果已经很多了,谁会在乎它有多大”,所以,让我们尽可能地找出最短的时间

另一个解决方案: 缓存一块原始数据 使用fread读取该数据的缓存

逐行阅读 从缓存中逐行读取,直到找到缓存结束或数据结束

读下一段并重复 抓取块的未处理的最后一部分(您正在寻找行分隔符的那一部分)并将其移动到前面,然后读取您定义的大小减去未处理数据大小的块,并将其放在未处理的块之后,然后,您就有了一个新的完整块。
重复逐行读取和此过程,直到文件完全读取

您应该使用大于任何预期行大小的缓存块


缓存大小越大,读取速度越快,但使用的内存越多。

问题到底是什么?对
fread
是否有限制?如果行非常短,这可能比
fread
方法慢(大量单独的小读取比较少的大读取有更多的IO开销).我和@OP在一条类似的船上,寻找最快的方式来读取300个文件,每个5 GB,一行一行。我要做很多不同大小的速度测试,但我想知道fread()1KB?1 MB?1 GB?我的服务器只有4 GB的RAM,所以可能不是GIG。在另一方面,将多个插件合并到MySQL的一个大插入中,什么是插入查询大小的一个好的起点?关于缓存大小的一个问题是,如果您使用的是命令行PHP或Web PHP,如果您使用的是Web PHP,则需要考虑T。它可能会重复使用同一个线程,如果你提高了很多内存的使用率,它会把它拖到下一次重复使用,你的内存的总体使用率会保持很高。关于你的缓存的大小,我会说1k非常小,1G肯定太大。因为你要做测试,你可以很好地测试多个数字,我我建议你尝试使用至少512k,可能不超过1到4MB或者类似的东西。只是想避免阅读太频繁,但你根本不需要避免阅读。我想说,如果你能阅读100到1000行,那么你就很好。IMHO
$blocksize = 50; // in "number of lines"
while (!feof($fh)) {
  $lines = array();
  $count = 0;
  while (!feof($fh) && (++$count <= $blocksize)) {
    $lines[] = fgets($fh);
  }
  doSomethingWithLines($lines);
}