javaoutputstreamgzipoutputstream

Why output is incomplete using OutputStreamWriter with GZIPOutputStream?


I'm hoping someone can shed light on a problem I'm having with the code below.

private static String encode(String data) throws IOException {
        try (
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            InputStream is = new ByteArrayInputStream(data.getBytes());
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            OutputStreamWriter writer = new OutputStreamWriter(new GZIPOutputStream(out));
            ) {
            char[] charBuffer = new char[data.length()];
            while (br.read(charBuffer) != -1) {
                writer.write(charBuffer);
            }
//          writer.close();
            return new String(Base64.encodeBase64(out.toByteArray()));
        }
    }

My test value is

This is some text that I can test some base64 encoding with.
I am getting a strange problem with the encoded value

when writer.close is commented out, my output is

H4sIAAAAAAAAAA==

When it's not commented, my output is

H4sIAAAAAAAAACWMzQ2DMBSD70jdwRP0VLED9y7wACuJRJKKZ37GJxTJF/uz/Y3J0eQ1E+IpKJowYLLSvOshozn7D1imOqcScCTF96sbYBmB0p0ZXKuVQPzWOi7M/1b747PjjN2WjRd08DfZcwAAAA==

This second output is the correct value and can be decoded back into the original value. It is my understanding that the process is as follows:

  1. Try code is executed
  2. Return value is evaluated and stored
  3. Resources are all closed
  4. The return value is returned.

Why then does the writer need to be closed for the output to be correct?


Solution

  • A GZIP output stream has to be told when to finish the compression and write the result to the underlying stream. close() implicitely flushes the writer and calls finish() on the GZIP stream.

    So, call at least flush() on the writer and finish() or close() of the GZIP stream, or close the writer, which will do all that and won't hurt anyway.