Отображение плоского текстового файла

В текстовом файле строки обнаруживаются с помощью \n в конце каждой строки. Для этого необходимо прочитать весь файл, а это большая проблема для больших файлов (скажем, 2 ГБ). Я ищу способ прочитать одну строку, не просматривая весь файл (хотя я знаю, что это должен быть сложный процесс).

  1. Первый известный мне способ — использовать fseek() со смещением; но это не практично.
  2. Создание плоского файла ключ/значение; но я не уверен, есть ли способ избежать загрузки всего в ОЗУ (это должно быть что-то вроде чтения массива в php).
  3. В качестве альтернативы, мы можем сделать несколько чисел в начале каждой строки для чтения. Я имею в виду, можно ли прочитать первые цифры в начале строки, пропустив содержимое строки (перейдя на следующую строку).

    768| line content is here
    769| another line
    770| something
    

При чтении только первых цифр общий объем данных, которые должны быть прочитаны, невелик даже для больших файлов.


person Googlebot    schedule 10.10.2011    source источник
comment
Вы всегда можете прочитать весь файл построчно в цикле, извлекая начальные цифры и отбрасывая оставшуюся строку. Однако вы должны помнить о производительности. Для файла размером 2 ГБ это может занять довольно много времени.   -  person Aleks G    schedule 10.10.2011
comment
Все, что я ищу, это избегать чтения всего файла построчно.   -  person Googlebot    schedule 10.10.2011
comment
Вам нужно прочитать определенные строки, которые можно проиндексировать по номеру строки? Если это так, просто выполните бинарный поиск. Прочитайте (скажем) 200 символов в середине файла, чтобы узнать номер строки. Затем повторите в любой из половин, пока не дойдете до правильной линии.   -  person Ed Heal    schedule 10.10.2011
comment
Я предполагаю, что вам придется прочитать весь файл - или, по крайней мере, до тех пор, пока вы не найдете интересующую вас строку - если только все строки не имеют одинаковую длину (что, как я вижу, у них нет).   -  person Aleks G    schedule 10.10.2011


Ответы (3)


Вам нужно прочитать определенные строки, которые можно проиндексировать по номеру строки? Если это так, просто выполните бинарный поиск. Прочитайте (скажем) 200 символов в середине файла, чтобы узнать номер строки. Затем повторите в любой из половин, пока не дойдете до правильной линии.

person Ed Heal    schedule 10.10.2011
comment
Линии имеют переменную длину. Как узнать номер строки, прочитав 200 символов в середине файла? - person Aleks G; 10.10.2011
comment
Если вы не найдете номер строки среди 200 символов, просто продолжайте читать вперед (или назад), пока не найдете. Затем, когда у вас есть номер строки, продолжайте алгоритм двоичного поиска :) - person Svish; 10.10.2011

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

Если файл всегда один и тот же (или, по крайней мере, не часто изменяется), я бы поместил его в базу данных или, по крайней мере, создал индексный файл (номер записи: смещение) и использовал этот fseek()

person dmitry    schedule 10.10.2011
comment
Что бы вы предложили для быстрого создания и обновления индексного файла? - person Googlebot; 10.10.2011
comment
Если вы пишете файл построчно, как вы упомянули в комментарии ниже, вы можете создать индекс параллельно. Просто накапливайте смещения (предыдущая длина данных) и сохраняйте для каждой строки в вашем файле запись фиксированной длины (например, используя пакет) в индексном файле. Вы можете обернуть все это в один класс и использовать где угодно. Чтобы прочитать строку, вы просто вычисляете смещение в индексе: linenum * recordlenght, fseek там и читаете байты длины записи, распаковываете, fseek в текстовом файле и читаете строку. Это может показаться сложным, но это распространенный подход к индексированию. - person dmitry; 10.10.2011

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

person agcala    schedule 27.12.2019