Java BufferedReader 返回文本文件的顶部?

发布于 2024-07-08 04:47:36 字数 307 浏览 15 评论 0原文

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

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

有想法吗? 包裹? 库? 代码?

谢谢 泰杰

I currently have 2 BufferedReaders initialized on the same text file. When I'm done reading the text file with the first BufferedReader, I use the second one to make another pass through the file from the top. Multiple passes through the same file are necessary.

I know about reset(), but it needs to be preceded with calling mark() and mark() needs to know the size of the file, something I don't think I should have to bother with.

Ideas? Packages? Libs? Code?

Thanks
TJ

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

千寻… 2024-07-15 04:47:36

缓冲读取器旨在顺序读取文件。 您正在寻找的是 java.io.RandomAccessFile< /a>,然后您可以使用 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" 是一个模式字符,它是 详细信息此处

顺序存取读取器之所以如此设置,是因为它们可以实现其缓冲区,并且无法在其脚下进行更改。 例如,提供给缓冲读取器的文件读取器只能由该缓冲读取器操作。 如果存在可能影响它的另一个位置,则可能会出现不一致的操作,因为一个读取器在文件读取器中前进了其位置,而另一个读取器希望它保持不变,现在您使用另一个读取器并且它位于未确定的位置。

The Buffered readers are meant to read a file sequentially. What you are looking for is the java.io.RandomAccessFile, and then you can use seek() to take you to where you want in the file.

The random access reader is implemented like so:

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();
}

The "rw" is a mode character which is detailed here.

The reason the sequential access readers are setup like this is so that they can implement their buffers and that things can not be changed beneath their feet. For example the file reader that is given to the buffered reader should only be operated on by that buffered reader. If there was another location that could affect it you could have inconsistent operation as one reader advanced its position in the file reader while the other wanted it to remain the same now you use the other reader and it is in an undetermined location.

趁微风不噪 2024-07-15 04:47:36

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

如果您担心性能,您是否已证明它是瓶颈? 我只会做最简单的事情,除非你有具体的理由,否则我不会担心它。 我的意思是,您可以将整个内容读入内存,然后对结果进行两次传递,但这又比用新读者从头开始阅读更复杂。

What's the disadvantage of just creating a new BufferedReader to read from the top? I'd expect the operating system to cache the file if it's small enough.

If you're concerned about performance, have you proved it to be a bottleneck? I'd just do the simplest thing and not worry about it until you have a specific reason to. I mean, you could just read the whole thing into memory and then do the two passes on the result, but again that's going to be more complicated than just reading from the start again with a new reader.

妞丶爷亲个 2024-07-15 04:47:36

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

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

The best way to proceed is to change your algorithm, in a way in which you will NOT need the second pass. I used this approach a couple of times, when I had to deal with huge (but not terrible, i.e. few GBs) files which didn't fit the available memory.

It might be hard, but the performance gain usually worths the effort

携余温的黄昏 2024-07-15 04:47:36

关于标记/重置:

BufferedReader 中的标记方法采用 readAheadLimit 参数,该参数限制在标记后在重置变得不可能之前可以读取的距离。 重置实际上并不意味着文件系统查找(0),它只是在缓冲区内查找。 引用Javadoc:

readAheadLimit - 在保留标记的同时限制可以读取的字符数。 读取这么多字符后,尝试重置流可能会失败。 大于输入缓冲区大小的限制值将导致分配一个大小不小于限制的新缓冲区。 因此,应谨慎使用大值。

About mark/reset:

The mark method in BufferedReader takes a readAheadLimit parameter which limits how far you can read after a mark before reset becomes impossible. Resetting doesn't actually mean a file system seek(0), it just seeks inside the buffer. To quote the 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.

鹤仙姿 2024-07-15 04:47:36

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

为什么不扩展这个类并让它在 constructor() 中执行 mark() 操作,然后在 topOfFile() 方法中执行eek(0) 操作。

BR,
~A

"The whole business about mark() and reset() in BufferedReader smacks of poor design."

why don't you extend this class and have it do a mark() in the constructor() and then do a seek(0) in topOfFile() method.

BR,
~A

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文