Я читаю файл, содержащий около 50 тыс. Строк, используя функцию file () в Php. Тем не менее, это дает ошибку из памяти, так как содержимое файла хранится в памяти в виде массива. Есть ли другой путь?
Кроме того, длина сохраненных строк является переменной.
Вот код. Также файл 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); }
EDIT после обновления вопроса и комментариев к ответу fabjoa :
Существует определенно что-то подозрительное, если файл 700 КБ съедает 140 МБ памяти с этим кодом, который вы дали (вы могли бы unset
отношение $ в конце каждой итерации). Подумайте об использовании отладчика, чтобы пройти через него, чтобы узнать, что произойдет. Вы также можете рассмотреть возможность перезаписи кода для использования функций CSV SplFileObject ( или их процедурных двоюродных братьев )
Пример 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 }
Для подхода ООП к итерации по файлу попробуйте SplFileObject
:
Пример SplFileObject :: fgets
$file = new SplFileObject("file.txt"); while (!$file->eof()) { echo $file->fgets(); }
SplFileObject :: следующий пример
// 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; }
Очень сильно (если не дублировать):
Если вы не знаете максимальную длину линии, и вам не удобно использовать магическое число для максимальной длины линии, вам необходимо выполнить первоначальное сканирование файла и определить максимальную длину строки.
Помимо этого, следующий код должен помочь вам:
// 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') ;. Не забудьте вернуться к первоначальному распределению памяти после завершения операции