10

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

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 ”?

4

7 回答 7

11

ready() != 有更多

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

要确定是否没有更多数据,请检查是否readLine()返回null

String line = in.readLine();
while(line != null){
   ...
   line = in.readLine();
}
于 2011-01-21T15:16:00.003 回答
8

您可以绕过的另一种方法in.ready()是:

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

您将继续阅读直到完成。这样您就不必担心in.ready().

于 2011-01-21T14:47:36.000 回答
4

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

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()

于 2011-01-21T14:47:45.063 回答
1

BufferedReader.ready()方法的行为与指定的一样:

Reader.ready()javadoc说明如下:

[返回]true如果 nextread()保证不阻塞输入,false否则。请注意,返回false并不能保证下一次读取会阻塞。

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

告诉这个流是否准备好被读取。如果缓冲区不为空,或者基础字符流已准备好,则缓冲字符流已准备就绪

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

于 2011-01-21T15:06:12.210 回答
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();
于 2011-01-21T15:17:18.137 回答
0

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

但真正的问题是,当我们完全读取数据流后,它会抛出 false.. 所以我们不知道流是完全读取还是底层流忙......

于 2011-07-19T12:44:34.280 回答
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;
        }
    }
于 2017-01-26T11:40:01.600 回答