Раньше я никогда не сталкивался с Java IO API, и сейчас я очень расстроен. Мне трудно поверить, насколько это странно и сложно, и как трудно было бы выполнить простую задачу.
Моя задача: у меня 2 позиции (начальный байт, конечный байт), pos1
и pos2
. Мне нужно прочитать строки между этими двумя байтами (включая начальный, не включая конечный) и использовать их в качестве строковых объектов UTF8.
Например, в большинстве языков сценариев это будет очень простой 1-2-3-строчный аналог (в Ruby, но он будет по сути одинаковым для Python, Perl и т. Д.):
f = File.open("file.txt").seek(pos1)
while f.pos < pos2 {
s = f.readline
# do something with "s" here
}
Это быстро приходит в ад с API Java IO;) На самом деле, я вижу два способа чтения строк (заканчивающихся \n
) из обычных локальных файлов:
- RandomAccessFile имеет
getFilePointer()
и seek(long pos)
, но это readLine () читает строки не-UTF8 (и даже не байтовые массивы), но очень странные строки со сломанной кодировкой и у него нет буферизации (что, вероятно, означает, что каждый вызов read*()
будет транслироваться в одну недопустимую ОС read()
=> довольно медленно).
- BufferedReader имеет отличный метод
readLine()
, и он может даже выполнять поиск с помощью skip(long n)
, но он не может определить четное число уже прочитанных байтов, не говоря уже о текущем позиция в файле.
Я пытался использовать что-то вроде:
FileInputStream fis = new FileInputStream(fileName);
FileChannel fc = fis.getChannel();
BufferedReader br = new BufferedReader(
new InputStreamReader(
fis,
CHARSET_UTF8
)
);
... и затем с помощью fc.position()
, чтобы получить текущую позицию чтения файла, и fc.position(newPosition)
, чтобы установить ее, но в моем случае это не работает: похоже, она возвращает позицию выполненного предварительного заполнения буфера BufferedReader, или что-то в этом роде - кажется, что эти счетчики округлены с шагом 16K.
Должен ли я реализовать все это самостоятельно, то есть интерфейс чтения файлов, который бы:
- позвольте мне получить / установить позицию в файле
- операции чтения из буферного файла
- разрешить чтение строк UTF8 (или, по крайней мере, разрешить такие операции, как «читать все до следующего
\n
»)
Есть ли более быстрый способ, чем реализовать все это самому? Я что-то наблюдаю?