>我目前在同一个文本文件上初始化了 2 个BufferedReader
。当我用第一个BufferedReader
读取完文本文件后,我使用第二个从顶部再次遍历文件。需要多次传递同一文件。
我知道reset()
,但它需要在调用mark()
之前,mark()
需要知道文件的大小,我认为我不应该打扰。
想法?包?库?法典?
谢谢泰杰
缓冲读取器用于按顺序读取文件。你要找的是java.io.RandomAccessFile,然后你可以使用seek()
把你带到文件中你想要的位置。
随机访问读取器是这样实现的:
try{
String fileName = "c:/myraffile.txt";
File file = new File(fileName);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.readChar();
raf.seek(0);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
"rw"
是一个模式字符,详见此处。
顺序访问读取器这样设置的原因是,它们可以实现缓冲区,并且脚下的东西不能改变。例如,提供给缓冲读取器的文件读取器只能由该缓冲读取器操作。如果有另一个位置可能影响它,您可能会有不一致的操作,因为一个读取器在文件读取器中前进了它的位置,而另一个读取器希望它保持不变,现在您使用另一个读取器并且它位于不确定的位置。
只创建一个新BufferedReader
从顶部读取有什么缺点?如果文件足够小,我希望操作系统缓存文件。
如果您担心性能,您是否证明这是一个瓶颈?我只会做最简单的事情,在你有具体的理由之前不要担心它。我的意思是,你可以把整个东西读到内存中,然后对结果进行两次传递,但这比用新读者从头开始阅读要复杂得多。
最好的方法是更改算法,以一种你不需要第二次传递的方式。我多次使用这种方法,当时我不得不处理不适合可用内存的大型(但并不可怕,即几 GB(文件。
这可能很难,但性能提升通常值得付出努力
关于标记/重置:
BufferedReader 中的 mark 方法采用 readAheadLimit 参数,该参数限制在无法重置之前标记后可以读取的距离。重置实际上并不意味着文件系统查找(0(,它只是在缓冲区内查找。引用Javadoc的话:
readAheadLimit - 限制在保留标记的同时可以读取的字符数。读取这么多字符后,尝试重置流可能会失败。大于输入缓冲区大小的极限值将导致分配大小不小于限制的新缓冲区。因此,应谨慎使用大值。
"关于 BufferedReader 中 mark(( 和 reset(( 的整个业务都带有糟糕的设计味道。
你为什么不扩展这个类,让它在 constructor(( 中做一个 mark((,然后在 topOfFile(( 方法中做一个 seek(0(。
溴,
~一个