最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; }
使用fopen
, fread
和fclose
按顺序读取文件:
$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');. 一旦操作完成,不要忘记回到初始的内存分配