GZIPOutputStream:增加压缩级别

18

java.util.zip.GZIPOutputStream没有提供一个构造函数参数或一个为其底层Deflater设置压缩级别的setter。

有解决此问题的方法,例如在这里所述:

GZIPOutputStream gzip = new GZIPOutputStream(output) {
    {
        this.def.setLevel(Deflater.BEST_COMPRESSION);
    }
};

我使用这个方法对一个10G的文件进行了GZIP压缩,与使用预设值DEFAULT_COMPRESSION相比,文件的大小没有减少一位。

此答案回答了该问题,指出在某些情况下设置级别可能不会按计划工作。为确保万无一失,我还尝试创建了一个新的Deflater

this.def = new Deflater(Deflater.BEST_COMPRESSION, true);

但文件大小仍未减小...

他们为什么没有提供访问Deflater级别的原因是什么?

还是上面的代码示例有问题?

Deflater级别起作用吗?

编辑:感谢评论

  1. 文件可以进一步压缩吗?

    它是一个UTF-8文本文件,使用默认压缩从10G压缩到10M。所以不知道压缩级别的细节,我认为它可以进一步压缩。

  2. DEFAULT_COMPRESSIONBEST_COMPRESSION之间的时间差异?

    我没有创建真正可靠的数字的时间。但我执行了每个压缩级别的代码约五次,并且两者花费大约相同的时间(2分钟+/- 5秒)。

  3. 使用gzip -v9的文件大小? 由gzip创建的文件比Java创建的文件小约15KB。所以对于我的特定用例来说,不值得进一步研究这个主题。

然而,上述三个基本问题仍然存在。是否有人曾成功地使用GZIPOutputStream的更高压缩级别减小文件?


1
你确定这个文件还能进一步压缩吗?它不是已经处于(有效)压缩格式中了吗?比如说MP4? - Ash
1
你能比较一下在命令行上压缩大小的方式,例如 gzip -v9 吗? - Peter Lawrey
1
无论大小,它都应该消耗更多的CPU。你可以计时它。 - Peter Lawrey
2个回答

20

是的,我使用Java GZIP工具略微提高了我的数据压缩比率。

class MyGZIPOutputStream 
    extends GZIPOutputStream {

    public MyGZIPOutputStream( OutputStream out ) throws IOException {
        super( out );
    } 

    public void setLevel( int level ) {
        def.setLevel(level);
    }
}

只需将其缠绕在您的流上并设置水平为,

new MyGZIPOutputStream( outputstream ).setLevel( Deflater.BEST_COMPRESSION );

这里是我在 3.2 GB 数据上尝试的性能结果,

默认压缩比数据压缩比率:1.3823362619139712

使用最佳压缩比数据压缩比率:1.3836412922501984

虽然改善不大,但仍有进步。


3
您可以复制GZIPOutputStream的定义,它是Deflater的简单包装器,并制作自己的版本,在创建Deflater实例时更改级别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接