【发布时间】:2008-09-16 08:25:33
【问题描述】:
System.IO.Compression.GZipStream 或 System.IO.Compression.Deflate 是否与 zlib 压缩兼容?
【问题讨论】:
标签: c# compression zlib
System.IO.Compression.GZipStream 或 System.IO.Compression.Deflate 是否与 zlib 压缩兼容?
【问题讨论】:
标签: c# compression zlib
我在使用 Git 对象时遇到了这个问题。在这种特殊情况下,它们将对象存储为带有 Zlib 标头的压缩 blob,该标头记录在 RFC 1950 中。您可以通过制作包含以下内容的文件来制作兼容的 blob:
0x78 0x01
CM = 8 = 放气CINFO = 7 = 32Kb 窗口FCHECK = 1 = 此标头的校验和位DeflateStream 的输出
DeflateStream,大端格式(MSB 优先)我做了自己的 Adler 实现
public class Adler32Computer
{
private int a = 1;
private int b = 0;
public int Checksum
{
get
{
return ((b * 65536) + a);
}
}
private static readonly int Modulus = 65521;
public void Update(byte[] data, int offset, int length)
{
for (int counter = 0; counter < length; ++counter)
{
a = (a + (data[offset + counter])) % Modulus;
b = (b + a) % Modulus;
}
}
}
差不多就是这样。
【讨论】:
DotNetZip 包括一个 DeflateStream、一个 ZlibStream 和一个 GZipStream,用于处理 RFC 1950、1951 和 1952。它们都使用 DEFLATE 算法,但每个帧和标题字节不同。
作为一个优势,DotNetZip 中的流在压缩下不会显示anomaly of expanding data size,根据内置流报告。此外,没有内置的 ZlibStream,而 DotNetZip 为您提供了它,以便与 zlib 进行良好的互操作。
【讨论】:
来自MSDN 关于System.IO.Compression.GZipStream:
该类表示gzip数据格式,使用行业标准算法进行无损文件压缩和解压。
来自zlib FAQ:
另一方面,zlib 中的 gz* 函数使用 gzip 格式。
所以 zlib 和 GZipStream 应该是可互操作的,但前提是您使用 zlib 函数来处理 gzip 格式。
据报道,System.IO.Compression.Deflate 和 zlib 不可互操作。
如果您需要处理 zip 文件(您可能不需要,但其他人可能需要),您需要使用 SharpZipLib 或其他第三方库。
【讨论】:
我使用 GZipStream 压缩来自 .NET XmlSerializer 的输出,并且使用 gunzip(在 cygwin 中)、winzip 和另一个 GZipStream 解压缩结果非常好。
作为参考,这是我在代码中所做的:
FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
using (GZipStream gzStream = new GZipStream(fs, CompressionMode.Compress))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyDataType));
serializer.Serialize(gzStream, myData);
}
然后,在c#中解压
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
using (Stream input = new GZipStream(fs, CompressionMode.Decompress))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyDataType));
myData = (MyDataType) serializer.Deserialize(input);
}
在 cygwin 中使用“文件”实用程序可以发现,使用 GZipStream 和 GNU GZip 压缩的同一文件之间确实存在差异(可能是其他人在此线程中所述的标题信息)。然而,这种差异在实践中似乎并不重要。
【讨论】:
gzip 是 deflate + 一些页眉/页脚数据,如校验和和长度等。因此,从一种方法可以使用另一种方法的流的意义上说,它们不兼容,但它们采用相同的压缩算法。
【讨论】:
他们只是使用 zlib 或 deflate 算法压缩数据,但不提供某些特定文件格式的输出。这意味着如果您将流按原样存储到硬盘驱动器,您很可能无法使用某些应用程序(gzip 或 winrar)打开它,因为文件头(幻数等)不包含在流中,您应该自己写。
【讨论】:
从 .NET Framework 4.5 开始,System.IO.Compression.DeflateStream 类使用 zlib 库。
来自班级的MSDN article:
该类表示 Deflate 算法,它是无损文件压缩和解压缩的行业标准算法。从 .NET Framework 4.5 开始,DeflateStream 类使用 zlib 库。因此,它提供了更好的压缩算法,并且在大多数情况下,压缩文件比早期版本的 .NET Framework 中提供的更小。
【讨论】:
我同意安德烈亚斯的观点。您可能无法在外部工具中打开该文件,但如果该工具需要一个流,您或许可以使用它。您还可以使用相同的压缩类将文件放回去。
【讨论】: