【问题标题】:java.io.IOException: BufferedInputStream is closed in Android 2.3java.io.IOException: BufferedInputStream 在 Android 2.3 中关闭
【发布时间】:2011-06-18 00:50:25
【问题描述】:

以下代码在 Android 1.5-2.2.1 中运行良好,但在 2.3 及更高版本中无法正常运行。

BufferedReader rd;
rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));

StringBuffer sb = new StringBuffer();
String line;
while ((line = rd.readLine()) != null){
    sb.append(line);
}
rd.close();

轨迹:

01-30 08:21:42.668: WARN/System.err(594): java.io.IOException: BufferedInputStream is closed
01-30 08:21:42.668: WARN/System.err(594):     at java.io.BufferedInputStream.streamClosed(BufferedInputStream.java:116)
01-30 08:21:42.728: WARN/System.err(594):     at java.io.BufferedInputStream.read(BufferedInputStream.java:274)
01-30 08:21:42.728: WARN/System.err(594):     at org.apache.harmony.luni.internal.net.www.protocol.http.UnknownLengthHttpInputStream.read(UnknownLengthHttpInputStream.java:40)
01-30 08:21:42.758: WARN/System.err(594):     at java.io.InputStreamReader.read(InputStreamReader.java:255)
01-30 08:21:42.758: WARN/System.err(594):     at java.io.BufferedReader.fillBuf(BufferedReader.java:128)
01-30 08:21:42.758: WARN/System.err(594):     at java.io.BufferedReader.readLine(BufferedReader.java:357)

这是一个问题吗? 2.3有什么变化吗??

【问题讨论】:

  • 代码中的哪个语句抛出了 IOException?
  • 这个:while ((line = rd.readLine()) != null)

标签: android http bufferedreader


【解决方案1】:

我也注意到了这一点。您可以做的一件事是在循环结束时检查 BufferedReader 的状态:

while((line = rd.readLine()) != null){
    sb.append(line);
    if (!rd.ready()) {
       break;
    }
}
rd.close();

但是,ready() 并不能保证您的流已经结束。它只检查流是否被阻塞或关闭。 见BufferedReader.ready() on developer.android.com

我认为这是 Android OS 2.3 及更高版本中引入的错误。请在官方 android 网站上贡献 bug 库,以鼓励 Google 修复此问题。不幸的是,已经有许多设备已经配备了操作系统版本 2.3 到 2.3.3。

您的情况是,您可能在一次读取中就到达了文件的末尾,并且流会自动关闭。我认为这是 Android 2.3 及更高版本中引入的错误。

glassonion 的帖子会起作用,但这种解决方法在长数据流上的执行速度会非常缓慢。

由于移动应用程序可能随时断开互联网连接,因此您正在读取的 InputStream 可能只是被阻止并等待更多数据。

更合适的方法可能是在新线程上打开一个套接字,读取数据并等待超时,以对冲连接中的任何缓慢。

The following article 很好地解释了处理停滞的连接。阅读摘要应该足以说服您。

所有优秀的网络应用程序都将包括超时检测和处理。无论您是编写客户端并需要检测任性的服务器,还是编写服务器并需要防止连接停止,超时处理都是错误处理的关键部分。

【讨论】:

  • 感谢您的帮助。我已经把它作为一个错误输入了。 code.google.com/p/android/issues/detail?id=14562
  • @sergi 不客气! glassonion 和我一起工作并出演了这个 bug。如果您从 Google 获得任何反馈,请告诉我们。 (反之亦然)
  • 对于其他所有人,请点击此页面底部的星号链接code.google.com/p/android/issues/detail?id=14562 以帮助 Google 优先考虑此错误修复。
  • @sergi 看起来来自 Google 的 Jesse 已经回复了您的错误报告。如果你有他可以测试的服务器,他们会调查。
  • 来自 Google 的 Jess 现在已经复制了这个问题,并在 android bugtracker 中发布了关于问题 14562 的解决方法(链接在之前的评论中)。
【解决方案2】:

解决方法如下。

InputStreamReader sr;
sr = new InputStreamReader(connection.getInputStream(), "UTF-8");
StringBuilder builder = new StringBuilder();
for (int bt = 0; (bt = sr.read()) != -1;) {
  builder.append((char)bt);
}
sr.close();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 2017-10-15
    • 2019-06-09
    • 2014-02-22
    • 2021-12-13
    • 2019-09-24
    • 1970-01-01
    相关资源
    最近更新 更多