чтение блока строк в файле с использованием php - PullRequest
2 голосов
/ 18 июля 2011

Учитывая, что у меня есть текстовый файл объемом 100 ГБ, содержащий миллионы строк текста.Как я могу прочитать этот текстовый файл по блокам строк, используя PHP?

Я не могу использовать file_get_contents();, потому что файл слишком большой.fgets() также читайте текст построчно, что, вероятно, займет больше времени, чтобы закончить чтение всего файла.

Если я буду использовать fread($fp,5030), где '5030' это некоторое значение длины, для которогочитать.Был бы случай, когда он не будет читать всю строку (например, остановка в середине строки), потому что он достиг максимальной длины?

Ответы [ 5 ]

4 голосов
/ 18 июля 2011

я не могу использовать file_get_contents ();потому что файл слишком большой.fgets () также читает текст за строкой, что, вероятно, займет больше времени, чтобы закончить чтение всего файла.

Не понимаю, почему вы не можете использовать fgets()

$blocksize = 50; // in "number of lines"
while (!feof($fh)) {
  $lines = array();
  $count = 0;
  while (!feof($fh) && (++$count <= $blocksize)) {
    $lines[] = fgets($fh);
  }
  doSomethingWithLines($lines);
}

Чтение 100 ГБ все равно займет время.

1 голос
/ 18 июля 2011

Я думаю, что вы должны использовать fread ($ fp, somesize) и проверить вручную, если вы нашли конец строки, в противном случае прочитайте другой фрагмент.

Надеюсь, это поможет.

1 голос
/ 18 июля 2011

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

1 голос
/ 18 июля 2011

Подход fread звучит как разумное решение.Вы можете определить, достигли ли вы конца строки, проверив, является ли последний символ в строке символом новой строки ('\n').Если это не так, то вы можете либо прочитать еще несколько символов и добавить их к существующей строке, либо обрезать символы из строки обратно до последней новой строки, а затем использовать fseek, чтобы изменить свою позицию в файле.

Боковая точка: Знаете ли вы, что чтение файла объемом 100 ГБ займет очень много времени?

0 голосов
/ 02 декабря 2016

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

Я согласен, что чтение 100 ГБ требует времени, поэтому я также согласен с тем, что нам нужно найти наиболее эффективный вариант, чтобы читать его, чтобы его было как можно меньше, вместо того, чтобы просто думать: «Кого волнует, сколько это, если уже много ", так что давайте выясним наше самое низкое возможное время.

Другое решение:

Кэшировать кусок необработанных данных

Используйте fread, чтобы прочитать кеш этих данных

Читать построчно

Строковое чтение из кэша до конца кэша или до конца найденных данных

Прочитать следующий фрагмент и повторить

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

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

Чем больше размер кэша, тем быстрее вы читаете, но чем больше памяти вы используете.

...