26

我目前BufferedReader在同一个文本文件上初始化了 2 秒。当我用第一个读完文本文件后BufferedReader,我使用第二个从顶部通过文件。需要多次通过同一个文件。

我知道reset(),但它需要在调用之前,mark()并且mark()需要知道文件的大小,我认为我不应该打扰。

想法?包裹?库?代码?

谢谢TJ

4

5 回答 5

29

缓冲读取器旨在按顺序读取文件。您正在寻找的是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"是一个模式字符,这里详细介绍

像这样设置顺序访问读取器的原因是,它们可以实现它们的缓冲区,并且不能在它们脚下改变事情。例如,提供给缓冲阅读器的文件阅读器只能由该缓冲阅读器操作。如果有另一个可能影响它的位置,您可能会出现不一致的操作,因为一个阅读器在文件阅读器中提升了它的位置,而另一个阅读器希望它保持不变,现在您使用另一个阅读器并且它位于未确定的位置。

于 2008-11-04T17:55:23.483 回答
26

仅仅创建一个新BufferedReader的从顶部读取的缺点是什么?如果文件足够小,我希望操作系统缓存文件。

如果您担心性能,您是否证明它是一个瓶颈?我只会做最简单的事情,在你有具体理由之前不要担心。我的意思是,您可以将整个内容读入内存,然后对结果进行两次传递,但这再次比仅使用新阅读器从头开始阅读要复杂得多。

于 2008-11-04T17:35:53.167 回答
3

最好的方法是改变你的算法,这样你就不需要第二遍了。当我不得不处理不适合可用内存的巨大(但并不可怕,即几 GB)文件时,我使用了这种方法几次。

这可能很难,但性能提升通常值得付出努力

于 2008-11-04T17:56:15.323 回答
1

关于标记/重置:

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.

于 2008-11-05T12:48:52.730 回答
-1

“关于 BufferedReader 中的 mark() 和 reset() 的整个业务都带有糟糕的设计味道。”

你为什么不扩展这个类并让它在构造函数()中做一个标记(),然后在topOfFile()方法中做一个seek(0)。

BR,
~A

于 2008-11-04T20:05:27.747 回答