最less的内存密集的方式来读取PHP中的文件

我正在阅读一个文件,其中包含约5万行使用PHP中的file()函数。 但是,由于文件的内容以数组的forms存储在内存中,所以会发生内存不足错误。 有没有其他的方法?

而且,存储的行的长度是可变的。

这是代码。 另外该文件是700kB不是mB。

private static function readScoreFile($scoreFile) { $file = file($scoreFile); $relations = array(); for($i = 1; $i < count($file); $i++) { $relation = explode("\t",trim($file[$i])); $relation = array( 'pwId_1' => $relation[0], 'pwId_2' => $relation[1], 'score' => $relation[2], ); if($relation['score'] > 0) { $relations[] = $relation; } } unset($file); return $relations; } 

使用fopenfreadfclose按顺序读取文件:

 $handle = fopen($filename, 'r'); if ($handle) { while (!feof($handle)) { echo fread($handle, 8192); } fclose($handle); } 

更新问题和评论之后编辑 fabjoa的答案 :

如果一个700kb的文件用你给出的代码吞噬了140MB的内存,你肯定会有些腥意(你可以在每次迭代结束时unset $关系)。 考虑使用debugging器来逐步了解发生了什么。 你也可以考虑重写代码来使用SplFileObject的CSV函数 ( 或者他们的程序表亲 )

SplFileObject :: setCsvControl示例

 $file = new SplFileObject("data.csv"); $file->setFlags(SplFileObject::READ_CSV); $file->setCsvControl('|'); foreach ($file as $row) { list ($fruit, $quantity) = $row; // Do something with values } 

对于遍历文件的OOP方法,请尝试SplFileObject

SplFileObject :: fgets示例

 $file = new SplFileObject("file.txt"); while (!$file->eof()) { echo $file->fgets(); } 

SplFileObject :: next示例

 // Read through file line by line $file = new SplFileObject("misc.txt"); while (!$file->eof()) { echo $file->current(); $file->next(); } 

甚至

 foreach(new SplFileObject("misc.txt") as $line) { echo $line; } 

非常相关(如果不重复):

  • 在Php中读取文件时如何节省内存?

如果您不知道最大行长度,并且您不习惯使用最大行长的幻数,那么您需要对文件进行初始扫描并确定最大行长度。

除此之外,下面的代码应该帮助你:

  // length is a large number or calculated from an initial file scan while (!feof($handle)) { $buffer = fgets($handle, $length); echo $buffer; } 

在操作过程中分配更多的内存,可能类似ini_set('memory_limit','16M');. 一旦操作完成,不要忘记回到初始的内存分配