使用BufferedReader从大型不断增长的文件中读取

时间:2010-07-08 16:59:58

标签: java file large-files bufferedreader

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

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()被称为
  5. 结果是每个readLine()获取写入过程输出的整行的一部分。它的行为正如预期的那样,因为每次调用它时,它都会到达文件的末尾,因此返回它所读取的内容。

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

    我可能通过更直接地处理FileReader并实质上重写BufferedReader来实现这种方法,但我不知道如何有效地执行此操作。我的实现可能不会像真正的BufferedReader一样快,并且我希望避免在 数据被读取的时候减慢程序的速度。

5 个答案:

答案 0 :(得分:2)

你可以从BufferedReader的源头开始并重写 String readLine(boolean ignoreLF)方法,如果在行尾之前找到EOF,则会导致问题。 (不幸的是,由于包装范围不能实现)

答案 1 :(得分:1)

BufferedReader并不意味着返回null,直到它到达流的确定结束。换句话说,我不希望它永远在返回null之后返回非null。

我有点惊讶它虽然给你提供了部分线条 - 我希望它会阻止直到它有一条完整的线条。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

BufferedReader reset fail after read to end of file