Как работать с очень большим текстовым файлом?

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

  • на основе CSV, в соответствии с RFC 4180, за исключением встроенных разрывов строк
  • , произвольный доступ для чтения к строкам, хотя в основном построчно и ближе к концу
  • добавление строк в конце
  • (изменение строк). Очевидно, что это требует перезаписи остальной части файла, это также редко, поэтому в данный момент не особенно важно

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

Я подумал об использовании отображенной в память области в качестве окна в файл, который перемещается, если запрашивается строка за пределами его диапазона. Конечно, на этом этапе у меня еще нет абстракции выше байтового уровня. Для реальной работы с содержимым у меня есть CharsetDecoder , дающий мне CharBuffer . Теперь проблема в том, Я могу нормально работать со строками текста в CharBuffer , но мне также нужно знать байтовое смещение этой строки в файле (чтобы сохранить кеш строковых индексов и смещений, поэтому я не необходимо просканировать файл с самого начала, чтобы найти конкретную строку).

Есть ли способ сопоставить смещения в CharBuffer с смещениями в сопоставлении ByteBuffer вообще ? Очевидно, это тривиально с ASCII или ISO-8859- *, в меньшей степени с UTF-8 и с ISO 2022 или BOCU-1 все станет совершенно уродливым (не то чтобы я действительно ожидал последних двух, но UTF-8 должен быть здесь по умолчанию - и все еще создает проблемы).

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

Тем не менее, мне интересно, можно ли вообще здесь пойти. Есть ли лучшие варианты?

ETA: Некоторые ответы на общие вопросы и предложения здесь:

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

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

Что касается того, что я обрисовал выше: Проблема, над которой я размышлял, заключалась в том, что я могу легко определить конец строки на уровне персонажа (U + 000D + U + 000A), но я не хотел предполагать, что это выглядит как 0A 0D на уровне байтов (который уже не работает, например, для UTF-16, где либо 0D 00 0A 00 , либо 00 0D 00 0A ). Я думал, что могу изменить кодировку символов, не жестко кодируя детали кодировки, которую я сейчас использую. Но я думаю, я мог бы просто придерживаться UTF-8 и использовать все остальное. Хотя почему-то кажется неправильным.

13
задан Joey 18 January 2011 в 13:31
поделиться