读取一行字符并获取文件位置
我正在从文本文件中读取连续的字符行。文件中字符的编码可能不是单字节。
在某些情况下,我想要获取下一行开始的文件位置,以便以后可以重新打开文件并快速返回到该位置。
问题
有没有一种简单的方法可以同时做到这两点,最好使用标准的Java库?
如果没有,合理的解决方法是什么?
理想解的属性
理想的解决方案是处理多个字符编码。这包括UTF-8,在UTF-8中,不同的字符可以由不同的字节数表示。理想的解决方案在很大程度上依赖于一个值得信赖、得到良好支持的库。最理想的是标准的Java库。第二好的选择是阿帕奇或谷歌的库。该解决方案必须是可扩展的。将整个文件读入内存不是解决方案。返回某个位置不应要求在线性时间内读取所有先前字符。详细信息
对于第一个需求,BufferedReader.readLine()
很有吸引力。但缓冲显然会干扰获得有意义的文件位置。
InputStreamReader
也可能会提前读取,从而干扰获取文件位置。来自InputStreamReader documentation:
为了能够有效地将字节转换为字符,可能会从基础流中提前读取比满足当前读取操作所需的更多的字节。
方法RandomAccessFile.readLine()
reads a single byte per character。
通过获取字符低位八位的字节值并将字符的高位八位设置为零,将每个字节转换为字符。因此,此方法不支持完整的Unicode字符集。
解决方案
如果从FileReader
构造BufferedReader
并保持FileReader
的实例可供代码访问,则应该能够通过调用:
fileReader.getChannel().position();
在调用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;
}
这将为您提供精确到您已经处理过的字节数,而不考虑底层标记或缓冲。您必须在统计中考虑行尾,因为它们是去掉的。
相关文章