【问题标题】:Java - size of compression output-byteArrayJava - 压缩输出字节数组的大小
【发布时间】:2009-07-30 16:50:40
【问题描述】:

当使用 java.util.zip.Deflater 的 deflate 方法时,必须提供一个 byte[] 作为参数,这个 byte[] 应该初始化为多大?我读过不能保证压缩数据会比未压缩数据更小。我应该使用一定百分比的输入吗? 目前我把它做成输入的两倍

【问题讨论】:

    标签: java size deflate


    【解决方案1】:

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

    【讨论】:

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

    为什么 Java 将类拼错为“deflater”?这个词是“放气剂”。天哪!抱歉,我不得不把它从我的胸膛中解脱出来。

    如前所述,预期用途是继续调用deflate,直到您从压缩中获得所有输出。但是,如果您真的想在一次调用中完成,那么 deflate 可以扩展数据的数量是有限的。 zlib 中有一个函数,不幸的是 Java 没有提供名为 deflateBound() 的函数,它提供了该上限。您可以只使用该函数的保守界限,并在此处复制相关行:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多