Alek Storm
Alek Storm

Reputation: 777

Decompressing gzipped data with Inflater in Java

I'm trying to decompress gzipped data with Inflater. According to the docs,

If the parameter 'nowrap' is true then the ZLIB header and checksum fields will not be used. This provides compatibility with the compression format used by both GZIP and PKZIP.

Note: When using the 'nowrap' option it is also necessary to provide an extra "dummy" byte as input. This is required by the ZLIB native library in order to support certain optimizations.

Passing true to the constructor, then attempting to decompress data results in DataFormatException: invalid block type being thrown. Following the instructions in this answer, I've added a dummy byte to the end of setInput()'s parameter, to no avail.

Will I have to use GZIPInputStream instead? What am I doing wrong?

Upvotes: 4

Views: 5473

Answers (2)

Mark Adler
Mark Adler

Reputation: 112239

The Java documentation is incorrect or at least misleading:

nowrap - if true then support GZIP compatible compression

What nowrap means is that raw deflate data will be decompressed. A gzip stream is raw deflate data wrapped with a gzip header and trailer. To fully decode the gzip format with this class, you will need to process the gzip header as described in RFC 1952, use inflater to decompress the raw deflate data, compute the crc32 of the uncompressed data using that class, and then verify the crc and length (modulo 2^32) in the gzip trailer, again as specified in the RFC.

Upvotes: 7

leonbloy
leonbloy

Reputation: 75896

I think that to read a GZIP stream it's not enough to set nowrap=true, you must also consume the gzip header, which is not part of the compressed stream. See eg. readHeader() in this implementation

Upvotes: 2

Related Questions