我有这样的代码来使用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
返回null
,ready
似乎也会返回true
。但是为什么不同Reader
的行为会有所不同?
更新
我知道读取文本文件的正常方法(就像Peter和Ali所说的那样)。但我从同事那里读到了那段代码,并意识到我不知道ready
方法。然后我读了JavaDoc,但不理解block
。然后我做了一个测试并发布了这个问题。所以,提出这个问题的更好方法可能是:
输入何时会被阻止?如何使用ready
方法(或为什么不使用它)?为什么这两个Reader
s(FileReader
和StringReader
)在ready
方法方面表现不同?
答案 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)
你做的是错的。 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