【发布时间】:2015-08-18 02:33:18
【问题描述】:
我正在从文本文件中读取连续的 字符 行。文件中字符的编码可能不是单字节的。
在某些时候,我想获取下一行开始的文件位置,以便稍后我可以重新打开文件并快速返回到该位置。
问题
有没有一种简单的方法可以做到这两点,最好是使用标准 Java 库?
如果不是,什么是合理的解决方法?
理想解决方案的属性
理想的解决方案是处理多种字符编码。这包括 UTF-8,其中不同的字符可以用不同的字节数表示。一个理想的解决方案主要依赖于一个值得信赖的、得到良好支持的库。最理想的是标准 Java 库。其次是 Apache 或 Google 库。解决方案必须是可扩展的。将整个文件读入内存不是解决方案。返回一个位置不需要在线性时间内读取所有先前的字符。
详情
对于第一个要求,BufferedReader.readLine() 很有吸引力。但是缓冲显然会干扰获得有意义的文件位置。
不太明显,InputStreamReader 也可以提前读取,干扰获取文件位置。来自InputStreamReader documentation:
为了实现字节到字符的高效转换,可能会从底层流中提前读取比满足当前读取操作所需的更多的字节。
方法RandomAccessFile.readLine()reads a single byte per character。
通过获取字符低八位的字节值并将字符的高八位设置为零,将每个字节转换为字符。因此,此方法不支持完整的 Unicode 字符集。
【问题讨论】:
-
您需要完整的 unicode 支持吗?
-
作为一个 FYI,我认为大多数具有
readLine()的 java 类也会修剪尾随空格/换行符,所以即使你只支持 ASCII,你的偏移量仍然会关闭 -
@dkatzel - 仅是 Java 支持的 - 16 位 unicode 字符,IIUC 被称为基本多语言平面。是的,我从类文档中看到
BufferedReader.getLine()和RandomAccessFile.readLine()都从返回值中读取和剥离行终止符。但是,我认为剥离只会影响返回值,而不是文件位置。 -
@Andy_Thomas 正确,但是,如果您尝试通过
line.length()计算文件位置,则由于剥离了终止符,计算将被关闭 -
@AndyThomas
Charset类本身甚至必须支持遗留错误这一事实表明,这里没有适用于所有可能的字符编码的简单解决方案。阅读文本文件是一个令人惊讶的难题。