我正在从文本文件中读取连续的字符行.文件中字符的编码可能不是单字节.
在某些时候,我想获得下一行开始的文件位置,这样我可以稍后重新打开文件并快速返回到该位置.
是否有一种简单的方法可以做到这两点,最好是使用标准的Java库?
如果没有,什么是合理的解决方法?
理想的解决方案是处理多种字符编码.这包括UTF-8,其中不同的字符可以用不同的字节数表示.理想的解决方案主要依赖于受信任且支持良好的库.最理想的是标准Java库.第二好的是Apache或Google库.解决方案必须是可扩展的.将整个文件读入内存不是一种解决方案.返回位置不应要求在线性时间内读取所有先前字符.
对于第一个要求,BufferedReader.readLine()
是有吸引力的.但缓冲显然会干扰获得有意义的文件位置.
不太明显,InputStreamReader
也可以提前读取,干扰获取文件位置.从InputStreamReader文档:
为了能够有效地将字节转换为字符,可以从基础流中提取比满足当前读取操作所需的更多字节.
该方法RandomAccessFile.readLine()
每个字符读取一个字节.
通过取字符的低八位的字节值并将字符的高八位设置为零,将每个字节转换为字符.因此,此方法不支持完整的Unicode字符集.
如果你BufferedReader
从a 构造一个FileReader
并保留FileReader
代码可访问的实例,你应该能够通过调用获得下一行的位置:
fileReader.getChannel().position();
Run Code Online (Sandbox Code Playgroud)
打电话给bufferedReader.readLine()
.
该BufferedReader
可以用大小为1的输入缓冲区,如果你愿意来换取位置精度性能提升构造.
备用解决方案 自己跟踪字节会出现什么问题:
long startingPoint = 0; // or starting position if this file has been previously processed
while (readingLines) {
String line = bufferedReader.readLine();
startingPoint += line.getBytes().length;
}
Run Code Online (Sandbox Code Playgroud)
无论基础标记或缓冲如何,这都可以使字节数精确到您已处理的内容.你必须考虑你的计数中的行结尾,因为它们被剥离了.