BufferedReader.ready()方法是否确保readLine()方法不返回NULL?

时间:2011-03-09 11:04:42

标签: java file-io

我有这样的代码来使用BufferedReader读取文本文件:

BufferedReader reader=null;
    try {
        reader = new BufferedReader(new FileReader("file1.txt"));

        while (reader.ready()) {
            final String line = reader.readLine();
            System.out.println("<"+line+">");
        } catch (..)
    {
        ...
    }

它正常工作但Findbugs报告了一个警告:

  

NP_DEREFERENCE_OF_READLINE_VALUE:The   调用readLine()的结果是   在没有检查的情况下解除引用   如果结果为null。如果没有   要读取的更多行文本,readLine()   将返回null和解除引用   这将生成一个空指针   异常。

当我将FileReader更改为StringReader时,即

BufferedReader reader=null;
    try {
        reader = new BufferedReader(new StringReader("ABCD"));

        while (reader.ready()) {
            final String line = reader.readLine();
            System.out.println("<"+line+">");
        } catch (..)
    {
        ...
    }

readLine方法返回null,而ready方法始终返回true - 实际上这是一个无限循环。

即使readLine返回nullready似乎也会返回true。但是为什么不同Reader的行为会有所不同?

更新

我知道读取文本文件的正常方法(就像Peter和Ali所说的那样)。但我从同事那里读到了那段代码,并意识到我不知道ready方法。然后我读了JavaDoc,但不理解block。然后我做了一个测试并发布了这个问题。所以,提出这个问题的更好方法可能是:

输入何时会被阻止?如何使用ready方法(或为什么不使用它)?为什么这两个Reader s(FileReaderStringReader)在ready方法方面表现不同?

4 个答案:

答案 0 :(得分:15)

ready方法告诉我们是否准备好读取流。

想象一下您的流正在从网络套接字读取数据。在这种情况下,流可能没有结束,因为套接字尚未关闭,但它可能还没有为下一个数据块做好准备,因为套接字的另一端没有再推送任何数据。

在上面的场景中,我们无法再读取任何数据,直到远端推送它,所以我们必须等待数据可用,或者关闭套接字。 ready()方法告诉我们数据何时可用。

答案 1 :(得分:12)

Reader.ready()和InputStream.available()很少像你想的那样工作,我不建议你使用它们。要阅读文件,您应该使用

String line;
while ((line = reader.readLine()) != null)
    System.out.println("<"+line+">");

答案 2 :(得分:6)

以下是Javadocs所说的内容:

  

判断此流是否已准备好进行读取。如果缓冲区不为空,或者基础字符流已准备就绪,则缓冲字符流就绪。

因此,如果底层流也准备就绪,则认为BufferedReader已准备就绪。由于BufferedReader是一个包装器,因此这个底层流可以是任何Reader实现;因此ready()的语义是在接口上声明的语义:

  

如果保证下一个read()不阻止输入,则返回true,否则返回false。请注意,返回false并不能保证下一次读取将被阻止。

所以你只能得到计时保证,即read()不会阻止。调用ready()的结果绝对不会告诉您从read()调用中返回的内容,因此不能用于忽略空检查。

答案 3 :(得分:1)

请看the API for ready

你做的是错的。 ready()仅告诉您流是否可读且有效。阅读该链接上的返回评论。

您想要做的是:

String thisLine;

//Loop across the arguments
for (int i=0; i < args.length; i++) {

  //Open the file for reading
  try {
    BufferedReader br = new BufferedReader(new FileReader(args[i]));
    while ((thisLine = br.readLine()) != null) { // while loop begins here
      System.out.println(thisLine);
    } // end while 
  } // end try
  catch (IOException e) {
    System.err.println("Error: " + e);
  }
} // end for