21

我正在使用类BufferedReader在缓冲区中逐行读取。在读取缓冲区中的最后一行时,我想再次从缓冲区的开头开始读取。我已经阅读了mark()and reset(),我不确定它的用法,但我认为他们不能帮助我解决这个问题。

有谁知道在到达最后一行后如何从缓冲区的开头开始读取?就像我们可以seek(0)使用RandomAccessFile?

4

3 回答 3

42

标记/重置是您想要的,但是您不能在 BufferedReader 上真正使用它,因为它只能重置一定数量的字节(缓冲区大小)。如果您的文件比这大,它将无法正常工作。没有“简单”的方法可以做到这一点(不幸的是),但它并不难处理,你只需要一个原始 FileInputStream 的句柄。

FileInputStream fIn = ...;
BufferedReader bRead = new BufferedReader(new InputStreamReader(fIn));

// ... read through bRead ...

// "reset" to beginning of file (discard old buffered reader)
fIn.getChannel().position(0);
bRead = new BufferedReader(new InputStreamReader(fIn));

(注意,不建议使用默认字符集,仅使用简化示例)。

于 2011-03-24T16:21:30.063 回答
5

是的,标记和重置是您想要使用的方法。

// set the mark at the beginning of the buffer
bufferedReader.mark(0);

// read through the buffer here...

// reset to the last mark; in this case, it's the beginning of the buffer
bufferedReader.reset();
于 2011-03-24T15:40:35.987 回答
0

这对我来说解决了这个问题。我正在逐行读取文件。我很早就在我的程序中做一个 BufferedReader 。然后,我检查 readLine 是否为 null 并执行 myFile.close,然后执行新的 BufferedReader。第一次通过时,readLine 变量将为 null,因为我在全局范围内设置它,然后还没有完成 readLine。该变量是全局定义的并设置为空。结果,发生了一个关闭的新 BufferedReader。如果我在程序的一开始没有执行 BufferedReader,那么这个 myFile.close 会在第一遍时抛出一个 NPE。

当文件逐行读取时,此测试失败,因为 readLine 不为空,测试中没有任何反应,文件解析的其余部分继续。

稍后,当 readLine 到达 EOF 时,它再次被赋值为 null。IE:第二次通过此检查还执行 myFile.close 和 new BufferedREader ,它将 readLine 重新设置回开头。

实际上,在我的循环内或循环外,此操作仅发生在 readLine 变量被全局设置为 null 或 EOF 时。在任何一种情况下,我都会执行“重置”以返回文件的开头和一个新的 BufferedReader。

if (readLineOutput == null) { 
//end of file reached or the variable was just set up as null
    readMyFile.close();
    readMyFile = new BufferedReader(new FileReader("MyFile.txt"));
                }
于 2017-07-20T00:37:38.237 回答