GZIPInputStream fails with IOException in Android 2.3, but works fine in all previous releases?

本小妞迷上赌 提交于 2019-11-30 05:21:43

问题


I updated my phone to Gingerbread today (2.3.2) and fired up an app I developed and saw that it failed to load its data. The app runs fine on every other version of Android I have tested from 1.6 to 2.2, but then an IOException in Gingerbread. Does anybody know if something changed in either GZipInputStream or URL.openStream()?

The problematic code is similar to the following:

InputStream in = null;
GZIPInputStream zin = null;
URL url = null;
try {
    url = new URL("http://www.test.com/gzipped_data.gz");
    in = url.openStream();
    zin = new GZIPInputStream(in);
}
catch (MalformedURLException e) { 
    return false;
} 
catch (IOException e) {
    return false;
}

In 1.6 to 2.2, this code works fine, in 2.3 I get an IOException with a message about the magic block being incorrect. I'm assuming something has changed with openStream that is messing up the MIME-type or something on this data. I read other places that openStream is not the most reliable way to handle HTTP connections, so this might be a good excuse to rework my connections code.


回答1:


I'm running into the same issue here. It looks like Gingerbread (2.3) changed the way GZipped streams are handled. Looking at the "magic block" characters indicates that openStream() automatically detects GZipped data and runs it through the correct stream decoder. Of course, if you attempt to run another GZIP decoder on the same stream, that will fail with an IOException.

There are a couple ways to handle this. The first way is to switch to HttpClient/HttpGet. BUT there is no guarantee that this also won't change in the future. Basically, that is a hack to get it working again. A more complete solution might be to do:

InputStream in = url.openStream();
GZIPInputStream zin;
try {
    zin = (GZIPInputStream)in;
} catch (Exception e) {
    zin = new GZIPInputStream(in);
}

For older versions of Android, an exception fires while attempting the cast and, on newer versions of Android, the cast succeeds. Abusing an exception handler this way is not pretty but it works.

This, of course, will be a problem for underlying data that is compressed or binary data that looks like it is GZIP compressed data. The Android devs think this change isn't a bug:

http://code.google.com/p/android/issues/detail?id=16227

I disagree. This is severe breakage.



来源:https://stackoverflow.com/questions/5131016/gzipinputstream-fails-with-ioexception-in-android-2-3-but-works-fine-in-all-pre

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!