我目前在同一个文本文件中初始化了2 BufferedReader
。当我用第一个BufferedReader
读取文本文件时,我使用第二个来从顶部再次传递文件。需要多次通过同一个文件。
我知道reset()
,但需要先调用mark()
,而mark()
需要知道文件的大小,我不认为我应该这样做打扰。
想法?包?库?码?
由于 TJ
答案 0 :(得分: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"
是一个模式字符detailed here。
这样设置顺序访问阅读器的原因是他们可以实现他们的缓冲区,并且不能在他们的脚下改变。例如,提供给缓冲读取器的文件读取器应仅由该缓冲读取器操作。如果有另一个位置可能会影响它,你可能会有一个不一致的操作,因为一个阅读器提升了它在文件阅读器中的位置,而另一个想要它保持相同,现在你使用另一个阅读器,它在一个未确定的位置。
答案 1 :(得分:25)
从顶部开始创建新的BufferedReader
有什么不利?如果文件足够小,我希望操作系统能够缓存该文件。
如果您担心性能问题,您是否证明它是瓶颈?我只做最简单的事情而不用担心它,直到你有特定的理由。我的意思是,你可以把整个事情都读到内存中,然后对结果进行两次传递,但是再次说这比使用新的阅读器从头再次阅读要复杂得多。
答案 2 :(得分:3)
最好的方法是改变算法,以不需要第二遍的方式。当我不得不处理那些不符合可用内存的巨大(但并不可怕,即几GB)文件时,我使用了这种方法几次。
可能很难,但性能提升通常值得付出努力
答案 3 :(得分:1)
关于标记/重置:
BufferedReader中的mark方法采用readAheadLimit参数,该参数限制在重置之前无法在标记之后读取的距离。重置实际上并不意味着文件系统搜索(0),它只是在缓冲区内寻找。引用Javadoc:
readAheadLimit - 限制在保留标记的同时可以读取的字符数。读取这么多字符后,尝试重置流可能会失败。大于输入缓冲区大小的限制值将导致分配一个大小不小于limit的新缓冲区。因此,应谨慎使用大值。
答案 4 :(得分:-1)
“BufferedReader中关于mark()和reset()的整个业务都很糟糕。”
为什么不扩展这个类并让它在构造函数()中执行mark(),然后在topOfFile()方法中执行seek(0)。
BR,
〜A