В настоящее время я пишу что-то, что нужно обрабатывать очень большие текстовые файлы (по крайней мере, несколько гигабайт). Здесь необходимо (и это исправлено):
- CSV-based, после RFC 4180, за исключением встроенных разрывов строк
- случайный доступ для чтения к линиям, хотя в основном по строкам и ближе к концу
- добавляющие строки в конце
- (изменение строк). Очевидно, что призывы к тому, чтобы остальная часть файла была переписана, это также редко, поэтому не особенно важно на данный момент.
Размер файла запрещает его полностью хранить в памяти (что также нежелательно, так как добавление изменений должно быть как можно скорее сохранено).
Я подумал о том, чтобы использовать область с отображением памяти в виде окна в файл, который перемещается, если запрашивается строка за пределами ее диапазона. Конечно, на этом этапе у меня все еще нет абстракции выше байтового уровня. Чтобы действительно работать с содержимым, у меня есть CharsetDecoder
, дающий мне CharBuffer
. Теперь проблема заключается в том, что я могу иметь дело с текстами строк, которые, возможно, очень хороши в CharBuffer
, но мне также нужно знать смещение байта этой строки в файле (чтобы сохранить кеш строк и смещений, t нужно снова отсканировать файл с начала, чтобы найти определенную строку).
Есть ли способ сопоставить смещения в 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 и все остальное. Похоже, что-то не так.