2013-02-13 2 views
7

Я пытаюсь проанализировать файл с разделителями табуляции размером ~ 1 ГБ.Прочитайте и проанализируйте содержимое очень большого файла

Где я запустить скрипт я получаю:

Fatal error: Allowed memory size of 1895825408 bytes exhausted (tried to allocate 1029206974 bytes) ... 

Мой сценарий на данный момент просто:

$file = file_get_contents('allCountries.txt') ; 

$file = str_replace(array("\r\n", "\t"), array("[NEW*LINE]", "[tAbul*Ator]"), $file) ; 

Я установил лимит памяти в php.ini -1, которое затем дает мне:

Fatal error: Out of memory (allocated 1029963776) (tried to allocate 1029206974 bytes) 

есть в любом случае, чтобы частично открыть файл, а затем перейти к следующей части, так меньше памяти израсходованы в одно время?

+1

Почему бы не обработать файл по строкам ?! – 2013-02-13 08:04:26

ответ

10

Да, вы можете прочитать его построчно:

$handle = @fopen("/tmp/inputfile.txt", "r"); 
if ($handle) { 
    while (($buffer = fgets($handle, 4096)) !== false) { 
     echo $buffer; 
    } 
    fclose($handle); 
} 
+1

Для файла с разделителем табулятуры используйте функцию fgetcsv() для простоты –

1

Вы уверены, что это fopen, который неисправного и не настройки тайм-аута вашего скрипта? По умолчанию обычно около 30 секунд или около того, и если ваш файл занимает больше времени, чем для чтения, это может привести к его отключению.

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

Если ни одна из перечисленных выше не является вашей проблемой, вы можете изучить с помощью fgets, чтобы прочитать файл по очереди, обрабатывая по мере поступления.

$handle = fopen("/tmp/uploadfile.txt", "r") or die("Couldn't get handle"); 
if ($handle) { 
    while (!feof($handle)) { 
     $buffer = fgets($handle, 4096); 
     // Process buffer here.. 
    } 
    fclose($handle); 
} 

Редактировать

PHP, кажется, не выдаст ошибку, он просто возвращает ложь.

Является ли путь к $rawfile правильным относительно того, где работает скрипт? Возможно, попробуйте установить абсолютный путь здесь для имени файла.

+0

Если я просто загружаю файл в память, это происходит примерно через 2 секунды, ошибка возникает с str_replace, но я попробую предложение по строке. – imperium2335

+0

Ошибка возникает с str_replace, потому что в этом случае php пытается скопировать тот же размер памяти в другую переменную – 2013-02-13 08:11:38

2

Вы должны использовать блоки для чтения файла. Проверьте ответ на этот вопрос. https://stackoverflow.com/a/6564818/1572528

Вы также можете попробовать использовать это для менее крупных файлов.

ini_set('memory_limit', '32M'); //max size 32m 
1

Да, используйте Еореп и Fread/fgets для этого:

http://www.php.net/manual/en/function.fread.php

string fread (resource $handle , int $length) 

Set $ ​​длины, сколько из файла, который вы хотите прочитать. $ handle сохраняет позицию для новых чтений, а затем fseek вы также можете установить позицию позже ....

Смежные вопросы