我目前BufferedReader
在同一个文本文件上初始化了 2 秒。当我用第一个读完文本文件后BufferedReader
,我使用第二个从顶部通过文件。需要多次通过同一个文件。
我知道reset()
,但它需要在调用之前,mark()
并且mark()
需要知道文件的大小,我认为我不应该打扰。
想法?包裹?库?代码?
谢谢TJ
我目前BufferedReader
在同一个文本文件上初始化了 2 秒。当我用第一个读完文本文件后BufferedReader
,我使用第二个从顶部通过文件。需要多次通过同一个文件。
我知道reset()
,但它需要在调用之前,mark()
并且mark()
需要知道文件的大小,我认为我不应该打扰。
想法?包裹?库?代码?
谢谢TJ
缓冲读取器旨在按顺序读取文件。您正在寻找的是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 参数,该参数限制在标记之后您可以读取多远,然后重置变得不可能。重置实际上并不意味着文件系统 seek(0),它只是在缓冲区内寻找。引用 Javadoc:
readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. After reading this many characters, attempting to reset the stream may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.
“关于 BufferedReader 中的 mark() 和 reset() 的整个业务都带有糟糕的设计味道。”
你为什么不扩展这个类并让它在构造函数()中做一个标记(),然后在topOfFile()方法中做一个seek(0)。
BR,
~A