Search code examples
javadeflate

Unexpected end of ZLIB input stream


I'm trying to round-trip a JSON string to a byte array with DeflaterOutputStream, but the code below throwing java.io.EOFException: Unexpected end of ZLIB input stream.

It works when you replace the string with "Hello world", or if you remove a few characters from the string below.

Any ideas?

public static void main(String[] args) throws IOException {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    DeflaterOutputStream deflate = new DeflaterOutputStream(bytes, new Deflater(Deflater.BEST_COMPRESSION, true));
    OutputStreamWriter writer = new OutputStreamWriter(deflate);
    writer.write("[1,null,null,\"a\",null,null,null,null,[1,null,null,null,null,null,null,null,null,null,null,null,null,0.0,0.0,null,null]");
    writer.flush();
    writer.close();

    InflaterInputStream inflaterIn = new InflaterInputStream(new ByteArrayInputStream(bytes.toByteArray()), new Inflater(true));
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inflaterIn));
    System.out.println(bufferedReader.readLine());
}

Java version (OSX):

java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)

Solution

  • I believe it's to do with the "no-wrap" option which you're passing "true" for in both the Deflater and Inflater. Setting both of these to false fixes the problem - although I'd recommend setting the string encoding in both places to (e.g. to UTF-8) instead of using the system default encoding.

    The docs for "nowrap" are fairly vague, but they state:

    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.

    Presumably this dummy input byte is missing, although it doesn't explain where it should go...