在.NET中同时支持deflate、gzip和zlib的一个库

4

首先,让我们定义一些常见混淆的术语:

deflate = compression_algorithm;
zlib = header + deflate + trailer;
gzip = header + deflate + trailer;

我正在寻找一个库,它可以让我基本上执行以下操作:
if(method == "gzip"){
    Response.Filter = new CompressionLibrary.OutputStream(Response.Filter, CompressionLibrary.Formats.GZIP);
}
else if(method == "deflate"){
    Response.Filter = new CompressionLibrary.OutputStream(Response.Filter, CompressionLibrary.Formats.DEFLATE);
}
else if(method == "zlib"){
    Response.Filter = new CompressionLibrary.OutputStream(Response.Filter, CompressionLibrary.Formats.ZLIB);
}

我正在寻找一种比较测试3种压缩格式在网页上使用的方法。我希望每种格式的deflate压缩算法是完全相同的实现。我已经修改了zlib.net以强制它按命令给我原始deflate(通过“未记录的功能”)......但是,添加gzip标头和尾巴有点超出了我的能力范围。
有没有人知道一个可以做到这一点的.NET库?
澄清:
HTTP 1.1的deflate压缩格式实际上是zlib压缩格式。Zlib是deflate的包装器;当压缩方法和级别相同时,它具有2字节头和4字节尾部,总是存在的。
Gzip在内部使用与zlib相同的压缩数据格式...即deflate(原始deflate,而不是HTTP 1.1 deflate [即zlib])。根据我自己的初步测试,gzipped数据比zlib大11比12。
deflate是用于压缩数据的压缩算法。当没有包装器方法(例如,deflated数据周围没有标题或尾部)时,我称其为“deflate” - 也许我应该称其为“原始deflate”。
我正在分析这些压缩方法及其在Web浏览器中的支持,并需要使用单个压缩方法来处理所有三种类型的压缩。

你是指压缩算法还是压缩方法中的“deflate”?请注意,如果你指的是方法,那么deflate等于zlib(请参见:http://www.gzip.org/zlib/zlib_faq.html#faq38)。我不确定你需要处理3种情况还是2种情况。如果是后者,那么System.IO.Compression类是否可行? - Joe
你想要确定什么?zlib只是deflate压缩方法(RFC 1951)和gzip文件格式(RFC 1952)的一种实现。比较gzip和zlib没有意义。或者你是想比较.NET实现的gzip和deflate与zlib实现的gzip和deflate吗? - Jim Mischel
我从定义开始,因为这些术语经常混淆。当提到deflate时,我并不是在谈论HTTP 1.1 deflate(那将是zlib格式:http://www.zlib.net/zlib_faq.html#faq39)。我会在我的问题中澄清。 - David Murdoch
2个回答

3

+1 谢谢!我刚在 CodePlex 上给 Cheeso 发了一条消息,指出主页上的一个错别字,没想到你就是 Cheeso。 :-D 你看过我在这个主题上的研究吗?链接 - David Murdoch
另外,您能否确认在使用DotNetZip的DEFLATE压缩方法时不会计算校验和? - David Murdoch
如果使用DeflateStream类,则不会计算CRC32。如果使用GZipStream,则会计算CRC32。我记不清ZLIB是否需要校验和,但是据我的记忆,ZLIB需要计算Adler32。另外,我还没有看过你的研究。我会去看看的。 - Cheeso

3
基于我对标准文档的阅读以及我在zlib、.NET gzip和deflate实现以及其他.NET压缩包上的工作,我得出以下结论:
1)“原始deflate”始终比您称之为“HTTP 1.1 deflate”的东西小,后者始终小于gzip。假设您使用相同的库来生成所有三个。也就是说,对于任何特定的压缩库,deflate < zlib < gzip。
2)尺寸差异非常小。deflate和zlib之间的差异通常只有几个字节。deflate和gzip之间的差异最多只有几十个字节。这在文件大小不管怎样都是成立的。
3)不同的deflate实现具有广泛变化的压缩比率和执行时间。例如,zlib实现比.NET 3.5实现提供更好的压缩和更快的执行。
4)不同实现之间的互操作性几乎达到了100%。也就是说,由一个库创建的deflate(或gzip)文件可以被任何其他库解压缩。我听说过这不是真的情况,但我无法构造出来。
5)由于CRC计算,创建gzip比创建zlib需要更长的时间。
我不知道是否有C#库允许您生成zlib或gzip文件,给定原始deflate数据,但是如果您研究标准文档,应该可以相当容易地构建它们。
我也不知道是否有任何支持“原始deflate”的浏览器。但是,我不能说我真正尝试过。我总是使用“HTTP 1.1 deflate”。

谢谢,这证实了我一直在推广的一切。而且,你们实际上使用的是原始压缩,而不是HTTP 1.1压缩(除非你不喜欢IE用户,所以你不会发送给他们可膨胀的数据)。 :-) 详情请参见此答案 - David Murdoch
我非常非常惊讶的发现,在压缩所需时间方面,CRC计算会产生实质性影响。DEFLATE是底层算法,它使用了Huffman编码和LZ77。这些都是需要占用CPU资源的算法;特别是LZ77需要在滑动窗口中搜索匹配项。CRC计算需要在已经压缩完成的数据上进行异或运算,所需时间比压缩要少得多。虽然CRC不是"免费"的,但我认为与任何重要的压缩负载相比,其消耗应该是微不足道的。 - Cheeso
我想看看能够复现你所描述的显著差异的代码。一个可能性是,在测量HTTP服务器场景中的压缩时,如果需要进行CRC校验,服务器会缓冲数据,反之则不会。这可能会导致延迟差异,但原因不是CRC操作本身,而是缓冲。 - Cheeso

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