我以前从未有过使用 Java IO API 的亲密体验,现在我真的很沮丧。我很难相信它是多么的奇怪和复杂,做一个简单的任务是多么的困难。
我的任务:我有 2 个位置(起始字节、结束字节)pos1
和pos2
. 我需要读取这两个字节之间的行(包括开始一个,不包括结束一个)并将它们用作 UTF8 String 对象。
例如,在大多数脚本语言中,它会是一个非常简单的 1-2-3-liner (在 Ruby 中,但对于 Python、Perl 等来说基本相同):
f = File.open("file.txt").seek(pos1)
while f.pos < pos2 {
s = f.readline
# do something with "s" here
}
Java IO API 很快就搞砸了;)事实上,我看到了两种\n
从常规本地文件中读取行(以 结尾)的方法:
- RandomAccessFile具有
getFilePointer()
andseek(long pos)
,但它的readLine()读取非 UTF8 字符串(甚至不是字节数组),但非常奇怪的字符串编码损坏,并且它没有缓冲(这可能意味着每个read*()
调用都将被转换为单个 undelying OSread()
= > 相当慢)。 - BufferedReader有很好的
readLine()
方法,它甚至可以用 做一些查找skip(long n)
,但是它无法确定已经读取的偶数字节,更不用说文件中的当前位置了。
我试过使用类似的东西:
FileInputStream fis = new FileInputStream(fileName);
FileChannel fc = fis.getChannel();
BufferedReader br = new BufferedReader(
new InputStreamReader(
fis,
CHARSET_UTF8
)
);
...然后fc.position()
用于获取当前文件读取位置并fc.position(newPosition)
设置一个,但在我的情况下它似乎不起作用:看起来它返回由 BufferedReader 完成的缓冲区预填充的位置,或者类似的东西 - 这些计数器似乎以 16K 为增量四舍五入。
我真的必须自己实现这一切吗,即一个文件阅读界面,它将:
- 允许我在文件中获取/设置位置
- 缓冲文件读取操作
- 允许读取 UTF8 字符串(或至少允许诸如“读取所有内容直到下一个
\n
”之类的操作)
有没有比自己实施更快的方法?我在监督什么吗?