.NET DeflateStream 与 Linux zlib 的区别

问题描述 投票:0回答:3

我需要Windows和Ubuntu之间的跨平台压缩/解压。据我了解,从 .NET 4.5 开始,DeflateStream 类使用 zlib 作为压缩库。我编写了两个小型测试程序来压缩数据,一个是在 Windows 上运行的 C# 程序,另一个是在 Ubuntu 上运行的“C”程序。 .NET 平台是 4.5.2。

C# 代码正在使用 CompressionLevel.Optimal

C 代码正在使用 Z_BEST_COMPRESSION

结果如下:

Input bytes: {9, 12, 13}
C# output: {227, 228, 225, 5, 0};
C output:  {120, 218, 227, 228, 225, 5, 0, 0, 67, 0, 35}

如您所见,C# 中压缩数据的长度为 5 个字节,而 C 中为 11 个字节。看来“C”zlib 在标头中添加了 2 个额外字节,在页脚中添加了 4 个额外字节。

如果需要,我可以分享代码。然而,它取自您在网上看到的标准示例,代码没有什么特别的。

我错过了什么吗?有办法解决吗?如果页眉和页脚始终保持不变,也许我总是可以添加额外的字节。问候。

.net compression zlib
3个回答
9
投票

首先,您需要了解 zlib 可以生成三种可能的格式。它们是原始 deflate (RFC 1951)、zlib 流(RFC 1950)和 gzip 流(RFC 1952),zlib 流是原始 deflate 包装在 zlib 头和尾部中(RFC 1952)。您的 C# 代码正在生成原始 deflate 流,而您的 C 代码正在生成 zlib 流。

您尚未展示您的代码,但您可以轻松地使用 zlib(在您的 C 代码中)生成原始 deflate 流,就像

DeflateStream
那样。不幸的是,NET 4.5 中没有类可以生成 zlib 流(在 C# 代码中)。但是,您可以轻松创建自己的 zlib 标头和预告片来包装原始 deflate 流。 (请参阅 RFC。)

但是,我强烈建议您根本不要使用 NET 4.5 zlib 接口例程。请使用 DotNetZip,它提供了 zlib 的全部功能的接口,而且最重要的是,它没有像 NET 4.5 中那样的错误,微软表示他们不会修复


2
投票

事实证明,这是 DeflateStream 和 zlib 之间一个非常古老的不兼容问题,如下所述:https://tlzprgmr.wordpress.com/2010/03/17/net-deflatestreamzlib-compatibility/

本质上,DeflateStream 不会向压缩数据添加所需的页眉或页脚。问候。


0
投票

我会依赖SharpZipLib,它已被广泛使用

根据 RFC 1950,ZLib 流是包装在标头和尾部中的原始 deflate 流。为了实现这一点,您可以使用 DeflaterOutputStream 和自定义配置的 Deflater:

DeflaterOutputStream compressStream = new(outputStream, new Deflater(Deflater.BEST_COMPRESSION, noZlibHeaderOrFooter: false));

指定

noZlibHeaderOrFooter: false
将防止遗漏 ZLib 标头和标尾。

© www.soinside.com 2019 - 2024. All rights reserved.