Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - size of compression output-byteArray

Tags:

java

size

deflate

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

like image 222
Clox Avatar asked Jul 30 '09 16:07

Clox


2 Answers

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();
like image 159
Laurence Gonsalves Avatar answered Nov 11 '22 11:11

Laurence Gonsalves


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;
like image 25
Mark Adler Avatar answered Nov 11 '22 09:11

Mark Adler