Java—压缩输出字节数组的大小

Java—压缩输出字节数组的大小,java,size,deflate,Java,Size,Deflate,使用java.util.zip.Deflater的deflate方法时,必须提供字节[]作为参数,该字节[]应初始化为多大?我已经读到,不能保证压缩的数据比未压缩的数据更小。我是否应该接受某个百分比的输入? 目前,我将其设置为输入的两倍在调用deflate后,调用finished查看是否还有更多输出。例如: byte[] buffer = new byte[BUFFER_SIZE]; while (!deflater.finished()) { int n = deflater.deflat

使用java.util.zip.Deflater的deflate方法时,必须提供字节[]作为参数,该字节[]应初始化为多大?我已经读到,不能保证压缩的数据比未压缩的数据更小。我是否应该接受某个百分比的输入?
目前,我将其设置为输入的两倍

在调用
deflate
后,调用
finished
查看是否还有更多输出。例如:

byte[] buffer = new byte[BUFFER_SIZE];
while (!deflater.finished()) {
  int n = deflater.deflate(buffer);
  // deal with the n bytes in out here
}
如果只想收集内存中的所有字节,可以使用ByteArrayOutputStream。例如:

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();

为什么Java将该类拼错为“deflater”?这个词是“平减指数”。天哪!对不起,我得把这件事说出来

如前所述,预期用途是不断调用
deflate
,直到获得压缩的所有输出。但是,如果您真的希望在单个调用中执行此操作,那么deflate可以扩展数据的数量是有限制的。不幸的是,Java中有一个函数名为
deflateBound()
,它提供了上限。您可以使用该函数的保守界限,并将相关行复制到此处:

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

如果你想得到一个大字节数组,在循环外创建一个
ByteArrayOutputStream
,然后通过
bos将每次迭代追加到该数组中。append(out,0,n)
谢谢你的回答。不过我不太明白。。。我是否必须多次调用deflate(),直到整个输入被压缩?我应该将缓冲区大小设置为什么?有没有什么教程或者类似的东西可以解释这一点?谢谢,我猜是有某种竞争条件,因为这正是我发布的第二个示例片段所做的。:-)是:您一直多次调用deflate(),直到整个输入被压缩。上面的代码就是这样做的。缓冲区大小实际上是一个“调整参数”。只要它是一个正整数,代码就可以工作,但性能会因您设置它的内容而有所不同。我可能只是将其设置为4096(4k)之类的值,然后仅在性能受到影响时才对其进行调整。我不知道有关于这方面的教程,但您可能会发现GZIPOutputStream的源代码很有启发性。它在内部使用Deflater。它碰巧使用了默认的缓冲区大小512,但在创建GZIPOutputStream时,实际上可以选择缓冲区大小。如果您有JDK源代码,可以在那里查看GZIPOutputStream。如果没有,您可以在此页面上看到它们: