Clox
Clox

Reputation: 1943

Java - size of compression output-byteArray

When using the deflate-method of java.util.zip.Deflater, a byte[] has to be supplied as the argument, how big should that byte[] be initialized to? I've read there's no guarantee the compressed data will even be smaller that the uncompressed data. Is there a certain % of the input I should go with? Currently I make it twice as big as the input

Upvotes: 5

Views: 3656

Answers (2)

Mark Adler
Mark Adler

Reputation: 112547

Why does Java misspell the class as "deflater"? The word is "deflator". Jeez! Sorry, had to get that off my chest.

As noted, the expected use is to keep calling deflate until you get all of the output from the compression. However, if you really want to do it in a single call, then there is a bound on the amount by which deflate can expand the data. There is a function in zlib that Java unfortunately does not make available called deflateBound() which provides that upper bound. You can just use the conservative bound from that function, with the relevant line copied here:

complen = sourceLen +
          ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;

Upvotes: 7

Laurence Gonsalves
Laurence Gonsalves

Reputation: 143314

After calling deflate, call finished to see if it still has more to output. eg:

byte[] buffer = new byte[BUFFER_SIZE];
while (!deflater.finished()) {
  int n = deflater.deflate(buffer);
  // deal with the n bytes in out here
}

If you just want to collect all of the bytes in-memory you can use a ByteArrayOutputStream. eg:

byte[] buffer = new byte[BUFFER_SIZE];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (!deflater.finished()) {
  int n = deflater.deflate(buffer);
  baos.write(buffer, 0, n);
}
return baos.toByteArray();

Upvotes: 8

Related Questions