Когда вы собираетесь просматривать произвольные файлы, включая потенциально большие файлы, я предполагаю, что существует вероятность того, что эти файлы на самом деле не являются текстовыми файлами или что вы можете столкнуться с файлами, которые имеют разные кодировки.
Поэтому, когда вы собираетесь просматривать такие файлы в виде текста с максимальной отдачей, вам следует подумать о том, какую кодировку вы хотите использовать, и убедиться, что сбои не повредят вашей работе. Конструктор, который вы используете с new String(buf)
, заменяет недопустимые символы, но излишне создавать новый экземпляр String
и добавлять его к StringBuilder
впоследствии.
Как правило, вы не должны идти так много обходных путей. Начиная с Java 7, вам не нужно RandomAccessFile
(или FileInputStream
), чтобы получить FileChannel
. Простое решение будет выглядеть как
// Instead of StandardCharsets.ISO_8859_1 you could also use Charset.defaultCharset()
CharsetDecoder decoder = StandardCharsets.ISO_8859_1.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith(".");
try(FileChannel fileChannel=FileChannel.open(Paths.get(filename),StandardOpenOption.READ)) {
//Don't load the whole file into the memory, therefore read 4096 bytes from position on
ByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_ONLY, position, 4096);
CharBuffer cb = decoder.decode(mappedByteBuffer);
LOGGER.debug(cb.toString()); // Debug purposes
}
Вы можете работать с полученным CharBuffer
напрямую или вызывать toString()
, чтобы получить экземпляр String
(но, конечно, избегайте делать это несколько раз). CharsetDecoder
также позволяет повторно использовать CharBuffer
, однако это может не так сильно повлиять на производительность. Чего вам определенно следует избегать, так это объединить все эти фрагменты в большую строку.