9

我的任务是(稍微有效地)逐行读取一个非常大的、不断增长的文件。这基本上是我现在正在做的事情:

BufferedReader rd = //initialize BufferedReader
String line;
while(true){
    while((line=rd.readLine())==null){
        try{
            Thread.sleep(1000);
        }catch(InterruptedException e){
            //handle exception
        }
    }
    //process line
}

所以我的 BufferedReader 只是挂在文件的末尾,直到有更多的东西要读取。这工作得很好,但有一个问题 - 如果在写入文件的进程正在写入一行时调用 readLine。然后第一次调用 readLine 将返回该行的第一部分,下一次调用将返回第二部分。但我真的需要这两部分在一起,我需要完整的线条。

更具体地说,我的问题发生在以下事件交错发生时:

  1. 写过程写了大部分的一行
  2. 调用 readLine()
  3. 编写过程完成该行并添加换行符
  4. 调用 readLine()

结果是每个 readLine() 都会选取写入过程正在输出的整行的一部分。它的行为符合预期,因为每次调用它时,它都会到达文件的末尾,因此返回它读取的内容。

所以本质上我需要的功能是一个 BufferedReader,它在 readLine 之前返回 null;一个不会给你一行,直到它后面有一个换行符,而不仅仅是它之后的 EOF。因此,如果它找到 EOF,它不会返回该点之前的行,它返回 null,并在文件被写入后返回该行并且后面有一个新行。

我可能可以通过更直接地处理 FileReader 并且本质上重写 BufferedReader 来实现一种粗略的方法,但我不太了解如何有效地做到这一点。我的实现可能不会像真正的 BufferedReader 那样快,并且我想避免在需要读取数据时减慢程序的速度。

4

5 回答 5

2

您可以从 BufferedReader 的源代码开始, String readLine(boolean ignoreLF)如果在行尾之前找到 EOF,则重写导致问题的方法。(不幸的是,由于包范围,它不能被继承)

于 2010-07-08T17:21:59.350 回答
1

BufferedReader在到达流的最终结束之前,它并不意味着返回 null。换句话说,我不希望它返回 null 后返回非 null。

我有点惊讶它给了你部分线路 - 我希望它会阻塞直到它有一个完整的线路。

于 2010-07-08T17:09:45.680 回答
0

您可以尝试http://www.gnu.org/software/kawa/api/gnu/text/LineBufferedReader.html
它使您能够回到行首

于 2010-07-08T17:08:53.523 回答
0

尝试始终使用pushback reader将最后一行向后推。

于 2010-07-08T17:23:30.403 回答
0

就像 stacker 说的,最好的方法是构造一个继承 Bufferedreader 的类。我发现当 BufferedReader 达到 EOF 时,它几乎注定要失败。如果您想继续阅读,或者检查是否有新内容,您可以随时重新打开并跳过。实际上,如果您确切知道要跳到哪里,则不会花费很长时间。看看这个问题的答案。他在一个阅读器上创建了一个reopenat() 函数,让阅读器刷新。

读取到文件末尾后,BufferedReader 重置失败

于 2014-07-08T21:08:59.323 回答