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; } }