java - 读取字符行并获取文件位置

标签 java nio java-io

我正在从文本文件中读取连续的 字符 行。文件中字符的编码可能不是单字节的。

在某些时候,我想获取下一行开始的文件位置,以便稍后我可以重新打开文件并快速返回到该位置

问题

有没有一种简单的方法可以做到这两点,最好是使用标准 Java 库?

如果不是,什么是合理的解决方法?

理想解决方案的属性

理想的解决方案是处理多种字符编码。这包括 UTF-8,其中不同的字符可以用不同的字节数表示。一个理想的解决方案主要依赖于一个值得信赖的、得到良好支持的库。最理想的是标准 Java 库。其次是 Apache 或 Google 库。解决方案必须是可扩展的。将整个文件读入内存不是解决方案。返回一个位置不需要在线性时间内读取所有先前的字符。

详情

对于第一个要求,BufferedReader.readLine() 很有吸引力。但是缓冲显然会干扰获得有意义的文件位置。

不太明显,InputStreamReader 也可以提前读取,干扰获取文件位置。来自 InputStreamReader documentation :

To enable the efficient conversion of bytes to characters, more bytes may be read ahead from the underlying stream than are necessary to satisfy the current read operation.

方法RandomAccessFile.readLine() reads a single byte per character .

Each byte is converted into a character by taking the byte's value for the lower eight bits of the character and setting the high eight bits of the character to zero. This method does not, therefore, support the full Unicode character set.

最佳答案

如果您从 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;
}

无论底层标记或缓冲如何,这都会为您提供与您已处理的内容准确的字节数。您必须在计数中考虑行尾,因为它们已被剥离。

关于java - 读取字符行并获取文件位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30627606/

相关文章:

java - 使用 RandomAccessFile 和 BufferedReader 来加速文件读取

java - RandomaccessFile,什么是真正的随机?

java - 使用Java进行文件分割的问题

java - 如何有效地连接对象列表中的多个 String 变量?

java - 在运行时获取类的泛型类型

java - 忽略非扩展类 JPA 的 @MappedSuperclass

java - 如何使用 ModelMapper 将外键从 dto 映射到实体对象?

java - 如何在单个 Java 服务器上处理超过一百万个并发客户端?

java - 如果文件不存在,PrinterWriter 是否会创建该文件?

Java 1.8 FileOutputStream 创建目录