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

我试图通过URL上的InputStreamReader(到某些Apache服务器上的文件)使用BufferedReader从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 ‘?

ready()!=有更多

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

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

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

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

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

你会继续阅读,直到你完成。 这样您就不必担心in.ready()的问题了。

我认为写这个的标准方法是尝试读取该行并validation它是否有时返回。 像这样的东西:

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

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

Reader.ready() javadoc说如下:

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

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

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

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

这是我们多年来一直使用的 – 不确定它是否是“标准”方法。 我想听听关于直接使用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(); 

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

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

如果你想使用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; } }