Получение одной строки в огромном файле с PHP
Как я могу получить определенную строку в текстовом файле 3 гигабайта. Строки разделяются символом \ n. И мне нужно иметь возможность получить любую линию по требованию.
Как это может быть сделано? Необходимо вернуть только одну строку. И я не хотел бы использовать системные вызовы.
Примечание. В том же вопросе возникает вопрос о том, как это сделать в bash. Я хотел бы сравнить его с PHP equiv.
Обновление: каждая строка имеет одинаковую длину всю дорогу.
5 Solutions collect form web for “Получение одной строки в огромном файле с PHP”
Не сохраняя какой-либо индекс в файле, вам нужно будет прочитать его все до тех пор, пока вы не встретите x число символов \ n. Я вижу, что nickf только что опубликовал какой-то способ сделать это, поэтому я не буду повторять его.
Чтобы сделать это несколько раз эффективным образом, вам нужно будет создать индекс. Храните некоторые известные позиции файла для определенных (или всех) номеров строк один раз, и затем вы можете использовать их для поиска в нужном месте с помощью fseek .
Изменить: если каждая строка имеет одинаковую длину, вам не нужен индекс.
$myfile = fopen($fileName, "r"); fseek($myfile, $lineLength * $lineNumber); $line = fgets($myfile); fclose($myfile);
Номер строки в этом примере равен 0, поэтому вам может потребоваться сначала вычесть его. Длина строки включает символ \n
.
Немного обсуждается проблема, и не упоминается, как следует ссылаться на «одну строку» (по числу, некоторой ценности внутри нее и т. Д.), Поэтому ниже просто догадка о том, чего вы хотите.
Если вы не прочь использовать объект (возможно, это может быть «слишком высокий уровень») и хотите ссылаться на строку путем смещения, тогда можно использовать SplFileObject
(доступный с PHP 5.1.0). См. Следующий базовый пример:
$file = new SplFileObject('myreallyhugefile.dat'); $file->seek(12345689); // seek to line 123456790 echo $file->current(); // or simply, echo $file
Этот конкретный метод ( seek
) требует сканирования через файл по строкам. Однако, если, как вы говорите, все линии имеют одинаковую длину, вы можете вместо этого использовать fseek
чтобы получить то, куда вы хотите идти намного быстрее .
$line_length = 1024; // each line is 1 KB line $file->fseek($line_length * 1234567); // seek lots of bytes echo $file->current(); // echo line 1234568
Вы сказали, что каждая строка имеет одинаковую длину, поэтому вы можете использовать fopen () в сочетании с fseek (), чтобы быстро получить строку.
Единственный способ, которым я могу это сделать, будет следующим:
function getLine($fileName, $num) { $fh = fopen($fileName, 'r'); for ($i = 0; $i < $num && ($line = fgets($fh)); ++$i); return $line; }
Хотя это не решение именно так, почему вам нужно вытащить одну строку из текстового файла 3 гигабайта? это проблема, или это может идти неторопливо? Если вам нужно вытащить много строк из этого файла в разные моменты времени, я бы определенно предложил поместить эти данные в какую-то БД. SQLite, может быть, ваш друг здесь, как очень простой, но не отличный, с множеством скриптов / людей, обращающихся к нему за один раз.