当前位置:  开发笔记 > 编程语言 > 正文

Zlib兼容的压缩流?

如何解决《Zlib兼容的压缩流?》经验,为你挑选了4个好方法。

System.IO.Compression.GZipStream或System.IO.Compression.Deflate与zlib压缩兼容吗?



1> 小智..:

我用Git对象遇到了这个问题.在这种特殊情况下,它们将对象存储为带有Zlib头的缩小blob,这在RFC 1950中有记录.您可以通过创建包含以下内容的文件来创建兼容的blob:

带有值的两个头字节(来自RFC 1950的CMF和FLG) 0x78 0x01

CM = 8 =放气

CINFO = 7 = 32Kb窗口

FCHECK = 1 =此标头的校验和位

C#的输出 DeflateStream

输入数据的Adler32校验和为DeflateStreambig-endian格式(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;
        }
    }
}

这就是它.



2> Cheeso..:

DotNetZip包括一个DeflateStream,一个ZlibStream和一个GZipStream,用于处理RFC 1950,1951和1952.所有这些都使用DEFLATE算法,但每个算法的成帧和头字节都不同.

作为一个优点,DotNetZip中的流没有表现出针对内置流报告的在压缩下扩展数据大小的异常.此外,没有内置的ZlibStream,而DotNetZip为您提供了与zlib良好的互操作性.



3> Rasmus Faber..:

从MSDN关于System.IO.Compression.GZipStream:

这个类代表gzip的数据格式,它采用无损文件压缩和解压的行业标准算法.

来自zlib FAQ:

另一方面,zlib中的gz*函数使用gzip格式.

所以zlib和GZipStream应该可以互操作,但前提是你使用zlib函数来处理gzip格式.

据报道,System.IO.Compression.Deflate和zlib不可互操作.

如果您需要处理zip文件(您可能不需要,但其他人可能需要),您需要使用SharpZipLib或其他第三方库.


re:关于zlib和DeflateStream,"据报道无法互操作".它们实际上不可互操作.有三个IETF RFC覆盖这个空间:1950年代表ZLIB,1951年代表DEFLATE,1952年代表GZIP.Deflate是压缩算法.ZLIB和GZIP是不同的格式,它们定义适用于压缩流的元数据,即"标题".zlib库实现了ZLIB和GZIP.为了使它有趣,ZLIB和GZIP都可以使用DEFLATE作为压缩机制.DeflateStream类生成一个裸的无头无条件流.难怪我们都感到困惑.

4> Isak Savo..:

我已经使用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中的'file'实用程序可以发现,使用GZipStream和GNU GZip压缩的同一文件确实存在差异(可能是其他人在此主题中声明的头信息).然而,这种差异在实践中似乎无关紧要.

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有