How to unzip Gzipped InputStream

How to unzip Gzipped InputStream

If you are working with HttpURLConnection on Android then you might encounter strange InputStream outputs like when you have a strange character encoding even though on the server side everything seems ok.

A problem I was encountered lately was when I needed to parse a RSS/Atom feed on Android. I was getting the following error:

parse error : line 1 column 0 not well-formed (invalid token)

Well it seems that in some cases you might run into gzipped content that is sent from the webserver. That means that the server compresses the content in order to shrink the size of the file. This way the speed of the response is increased..

It seems that in this case HttpURLConnection doesn’t do the unzipping work for you so you have to do it yourself!

I noticed that there are some over the internet that are saying that you can also disable the GZip compression by¬†setting the Accept-Encoding header to “identity” like so:

urlConnection.setRequestProperty("Accept-Encoding", "identity");

I wouldn’t recommend doing that unless you really need to. This is because GZip compression can speed up network communication and also save user’s band if it’s not on a wifi network.

Here is how to do it if you want to keep GZip compression:

public InputStream decompressGZipIfNeeded(InputStream input) throws IOException {
        InputStream decompressedStream;

        // we need only the first 2 bytes from the input stream
        byte[] magic = new byte[2];

        PushbackInputStream pushbackInputStream = new PushbackInputStream(input, 2);
        // read the first 2 bytes from the stream
        pushbackInputStream.read(magic, 0, 2);

        // reset the input stream so we can use it latter 
        pushbackInputStream.unread(magic);

        if (magic[0] == (byte) 0x1f && magic[1] == (byte) 0x8b) {
            // check if this is compressed with Gzip (see also GZIPInputStream.GZIP_MAGIC) and decompress the stream
            decompressedStream = new GZIPInputStream(pushbackInputStream);
        } else {
            // just return what we received
            decompressedStream = pushbackInputStream;
        }
        return decompressedStream;
    }

The code is not entirely mine, it is out there on the internet, I just added a few comments and minor renaming in order to be more readable and easy to understand.

Menu