Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decompressing gzipped data with Inflater in Java

Tags:

java

gzip

zlib

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?

like image 428
Alek Storm Avatar asked Oct 11 '25 13:10

Alek Storm


2 Answers

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.

like image 105
Mark Adler Avatar answered Oct 14 '25 02:10

Mark Adler


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

like image 27
leonbloy Avatar answered Oct 14 '25 03:10

leonbloy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!