Я читаю файл, содержащий вокруг 50k строк с помощью файла () функция в Php. Однако его предоставление из ошибки памяти начиная с содержания файла хранится в памяти как массив. Есть ли какой-либо другой путь?
Кроме того, длины сохраненных строк являются переменными.
Вот код. Также файл составляет 700 КБ не МБ.
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;
}
РЕДАКТИРОВАТЬ после обновления вопроса и комментариев к ответу fabjoa :
Определенно есть что-то подозрительное, если файл размером 700 КБ занимает 140 МБ памяти с этим код, который вы указали (вы можете отключить отношение
$ в конце каждой итерации). Подумайте об использовании отладчика, чтобы пройти через него и посмотреть, что произойдет. Вы также можете подумать о том, чтобы переписать код, чтобы использовать функции 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 example
$file = new SplFileObject("file.txt");
while (!$file->eof()) {
echo $file->fgets();
}
// 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;
}
Используйте fopen
, fread
и fclose
для последовательного чтения файла:
$handle = fopen($filename, 'r');
if ($handle) {
while (!feof($handle)) {
echo fread($handle, 8192);
}
fclose($handle);
}
выделить больше памяти во время операции, возможно, что-то вроде ini_set ('memory_limit ',' 16M ') ;. Не забудьте вернуться к начальному распределению памяти после завершения операции