gpt4 book ai didi

java - Deflater.setLevel() 有效吗?

转载 作者:搜寻专家 更新时间:2023-10-31 19:39:43 27 4
gpt4 key购买 nike

Deflater.setLevel()对我来说没有预期的效果。

static void test1() throws Exception {
byte[] output = new byte[20];
Deflater compresser = new Deflater();
// compresser.setLevel(Deflater.BEST_COMPRESSION);
compresser.setInput("blah".getBytes("UTF-8"));
compresser.finish();
int len = compresser.deflate(output);
System.out.println("len="+ len+ " " +Arrays.toString(output));
}

以上对我来说工作正常(Java 7),但是当我取消注释 compresser.setLevel() 行时,它会中断(deflate() 返回 0 字节) .除了 DEFAULT 之外,任何压缩级别都会发生同样的情况。更具体地说,它仅在水平集与构造函数中设置的水平集(显式或隐式,如此处)相同时才“起作用”(相反,它是无害的)——也就是说,它只能在无用时使用。

请参阅 Ideone 中的示例.

This question指向相同的问题,接受的答案基本上是这样说的:不要使用 setter 设置级别,在构造函数中执行。 IMO 远非令人满意 - 为什么 setLevel() 存在?它坏了还是我们遗漏了什么?

最佳答案

我深入研究了 JDK 源代码。它确实设定了水平。如果您在 setLevel() 之后使用 compresser.deflate(new byte[0]);,那么它将起作用。

发生的事情是,在 setLevel() 之后第一次调用 deflate() 会看到级别发生了变化,并调用 zlib 的 deflateParams() 函数来改变它。 deflateParams() 然后将压缩可用数据,但您请求 finish() 的事实不会传递。然后,JDK 实现不会使用 Z_FINISH 调用 deflate()。结果,您提供的数据被发送进行压缩,压缩器累积数据,但它不会发出压缩 block ,因为它没有被要求完成。所以你什么也得不到。

您需要在 setLevel() 之后调用 deflate() 才能实际设置级别。然后后续数据将使用新级别进行压缩。

重要的是要注意,在 setLevel() 之后的第一个 deflate() 调用之前提供的数据将使用 old 压缩级别。只有在 deflate() 调用之后提供的数据才会使用新级别。因此,如果在您的示例中,您只是在最后一个之后执行了另一个 deflate() ,它将应用 finish() 并且您将获得压缩数据,但它会使用默认压缩级别。

关于java - Deflater.setLevel() 有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17632314/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com