BufferedReader在应该的时候没有说“准备好”

时间:2011-01-21 14:40:16

标签: java url bufferedreader

我正在尝试使用 BufferedReader 通过URL上的InputStreamReader(到某些Apache服务器上的文件)从Web文档中读取文本。

String result = "";
URL url = new URL("http://someserver.domain/somefile");
BufferedReader in = null;
in = new BufferedReader(new InputStreamReader(url.openStream(), "iso-8859-1"));

result += in.readLine();

现在这很好用。但显然我希望读者不要只阅读一行,而是阅读文件中的一行 查看BufferedReader API,以下代码应该只是这样做:

while (in.ready()) {
    result += in.readLine();
}

即。当有更多行时读取所有行,当没有更多行时停止。但是这段代码不起作用 - 读者从不报告 ready()= true

我甚至可以在读取一行(从文件中读取正确的字符串)之前打印ready()值,但读者将报告' false '。

我做错了吗?当实际有东西需要读取时,为什么BufferedReader会准备好' false '?

7 个答案:

答案 0 :(得分:9)

ready()!=有更多

ready()并不表示有更多数据需要读取。它仅显示读取是否可以阻止该线程。在您阅读所有数据之前,它很可能会返回false。

如果readLine()返回null,请查看是否没有其他数据检查。

String line = in.readLine();
while(line != null){
   ...
   line = in.readLine();
}

答案 1 :(得分:6)

绕过in.ready()的另一种方法就是:

while ((nextLine = in.readLine()) != null) {
  result += nextLine;
}

在完成之前,您将继续阅读。这样您就不必担心in.ready()的问题。

答案 2 :(得分:3)

我认为编写此标准的标准方法是尝试读取该行并验证它是否在某个时间返回。像这样:

while ((String nextLine = in.readLine()) != null) {
    //System.out.println(nextLine);
    result += nextLine;
}

因此,您只需继续操作,直到从流中返回null。有关其他信息,请参阅此处:

http://download.oracle.com/javase/1.5.0/docs/api/java/io/BufferedReader.html#readLine()

答案 3 :(得分:2)

BufferedReader.ready()方法的行为符合指定:

Reader.ready() javadoc说明如下:

  

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

然后BufferedReader.ready() javadoc说出以下内容:

  

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

如果将这两者放在一起,很明显BufferedReader.ready() 可以在可用字符的情况下返回false。简而言之,您不应该依赖ready()来测试逻辑文件结束或流结束。

答案 4 :(得分:0)

这是我们多年来一直使用的 - 不确定它是否是“标准”方法。我想听听关于直接使用URL.openURLStream()的利弊的评论,如果这导致了OP的问题。此代码适用于HTTP和HTTPS连接。

 URL  getURL = new URL (servletURL.toString() + identifier+"?"+key+"="+value);      
 URLConnection uConn = getURL.openConnection();

 BufferedReader br = new BufferedReader (new
                            InputStreamReader (uConn.getInputStream()));
 for (String s = br.readLine() ; s != null ; s = br.readLine()) {
      System.out.println ("[ServletOut] " + s);
      // do stuff with s
 }               
 br.close();

答案 5 :(得分:0)

基本上,BufferedReader.ready()方法可用于检查底层流是否已准备好向方法调用者提供数据....否则我们可以等待线程一段时间直到它准备就绪。

但真正的问题是,在我们完全读取数据流之后,它会抛出错误。 所以我们不知道流是否被完全读取或底层流是否忙......

答案 6 :(得分:0)

如果您想使用in.ready(),以下内容对我有用:

    for (int i = 0; i < 10; i++) {
        System.out.println("is InputStreamReader ready: " + in.ready());
        if (!in.ready()) {
            Thread.sleep(1000);
        } else {
            break;
        }
    }