java.io.IOException: BufferedInputStream закрыто в Android 2.3 - PullRequest
5 голосов
/ 30 января 2011

Следующий код работает в 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();

Stracktrace:

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

Ответы [ 2 ]

9 голосов
/ 04 марта 2011

Я тоже это заметил.Одна вещь, которую вы можете сделать, это проверить состояние BufferedReader в конце вашего цикла:

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

Однако, ready () не гарантирует, что ваш поток находится в конце.Он только проверяет, заблокирован ли поток или закрыт.См. BufferedReader.ready () на developer.android.com

Я думаю, что это ошибка, представленная в Android OS 2.3 и выше.Пожалуйста, внесите свой вклад в базу ошибок на официальном сайте Android, чтобы Google решил эту проблему.К сожалению, уже есть много устройств, которые уже поставлялись с версиями ОС от 2.3 до 2.3.3.

Ваша ситуация заключается в том, что вы, вероятно, достигли конца файла за одно чтение, и поток автоматически закрывается.Я думаю, что это ошибка, представленная в Android 2.3 и выше.

Пост Glassonion будет работать, но этот обходной путь будет работать очень медленно на длинных потоках данных.

Поскольку мобильные приложения могут потерять подключение к Интернету в любое время, InputStream, с которого вы читаете, может быть просто заблокирован и ожидает дополнительных данных.

Более правильный подход может состоять в том, чтобы открыть сокет в новом потоке, прочитать данные и подождать с таймаутом, чтобы застраховаться от любой медлительности в вашем соединении.

Следующая статья объясняет, как правильно обрабатывать заблокированные соединения.Чтение сводки должно быть достаточно, чтобы убедить вас.

Все хорошие сетевые приложения будут включать в себя обнаружение и обработку тайм-аута.Независимо от того, пишете ли вы клиент, и вам нужно обнаружить ненормативную лексику, или вы пишете сервер, и вам нужно предотвращать остановленные соединения, обработка тайм-аута является важной частью обработки ошибок.

2 голосов
/ 04 марта 2011

обходной путь ниже.

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...