Разбор больших текстовых файлов с помощью PHP без уничтожения сервера - PullRequest
1 голос
/ 10 августа 2009

Я пытаюсь прочитать несколько больших текстовых файлов (между 50M-200M), выполняя простую замену текста (по существу, xml, который у меня был, не был должным образом экранирован в некоторых регулярных случаях). Вот упрощенная версия функции:

<?php
function cleanFile($file1, $file2) {
$input_file     = fopen($file1, "r");
$output_file    = fopen($file2, "w");
  while (!feof($input_file)) {
    $buffer = trim(fgets($input_file, 4096));
    if (substr($buffer,0, 6) == '<text>' AND substr($buffer,0, 15) != '<text><![CDATA[')
    {
      $buffer = str_replace('<text>', '<text><![CDATA[', $buffer);
      $buffer = str_replace('</text>', ']]></text>', $buffer);
    }
   fputs($output_file, $buffer . "\n");
  }
  fclose($input_file);
  fclose($output_file);     
}
?>

Чего я не понимаю, так это того, что для самых больших файлов, около 150 МБ, использование памяти PHP выходит за пределы графика (около 2 ГБ), прежде чем происходит сбой. Я думал, что это самый эффективный способ чтения больших файлов. Есть ли какой-то метод, который мне не хватает, который был бы более эффективным для памяти? Возможно, какая-то настройка, которая хранит вещи в памяти, когда они должны быть собраны?

Другими словами, это не работает, и я не знаю почему, и, насколько я знаю, я не делаю вещи неправильно. Любое направление для меня, чтобы пойти? Спасибо за любой вклад.

Ответы [ 3 ]

3 голосов
/ 10 августа 2009

PHP на самом деле не предназначен для этого. Перенесите работу в другой процесс и вызовите ее или запустите из PHP. Я предлагаю использовать Python или Perl .

1 голос
/ 10 августа 2009

Из моего скудного понимания сборки мусора в PHP может помочь следующее:

  1. unset $buffer когда вы закончите записывать его на диск, явно попросите GC очистить его.
  2. поместите блок if в другую функцию, чтобы ГХ запускался при выходе из этой функции.

Причина этих рекомендаций заключается в том, что я подозреваю, что сборщик мусора не освобождает память, поскольку все выполняется внутри одной функции, а сборщик мусора - мусор.

0 голосов
/ 10 августа 2009

Я ожидаю, что это потерпит неудачу во многих случаях. Вы читаете кусками по 4096 байт. Кто знает, что отсечка не будет в середине <text>? В этом случае ваш str_replace не будет работать.

Рассматривали ли вы использование регулярного выражения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...