Zlib 兼容的压缩流?

发布于 2024-07-05 10:05:25 字数 88 浏览 7 评论 0原文

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

Are System.IO.Compression.GZipStream or System.IO.Compression.Deflate compatible with zlib compression?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

情徒 2024-07-12 10:05:26

DotNetZip 包括 DeflateStream、ZlibStream 和 GZipStream,用于处理 RFC 1950、1951 和 1952。 DEFLATE 算法,但每个算法的帧和头字节都不同。

作为一个优点,DotNetZip 中的流不会出现数据大小扩展的异常情况 在压缩下,根据内置流进行报告。 此外,没有内置的 ZlibStream,而 DotNetZip 为您提供了该功能,以便与 zlib 实现良好的互操作。

DotNetZip includes a DeflateStream, a ZlibStream, and a GZipStream, to handle RFC 1950, 1951, and 1952. The all use the DEFLATE Algorithm but the framing and header bytes are different for each one.

As an advantage, the streams in DotNetZip do not exhibit the anomaly of expanding data size under compression, reported against the built-in streams. Also, there is no built-in ZlibStream, whereas DotNetZip gives you that, for good interop with zlib.

只为一人 2024-07-12 10:05:26

来自 MSDN 关于 System.IO. Compression。 GZip 流:

此类代表 gzip 数据格式,它使用行业标准算法进行无损文件压缩和解压缩。

来自 zlib 常见问题解答

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

因此,zlib 和 GZipStream 应该是可互操作的,但前提是您使用 zlib 函数来处理 gzip 格式。

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

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

From MSDN about System.IO.Compression.GZipStream:

This class represents the gzip data format, which uses an industry standard algorithm for lossless file compression and decompression.

From the zlib FAQ:

The gz* functions in zlib on the other hand use the gzip format.

So zlib and GZipStream should be interoperable, but only if you use the zlib functions for handling the gzip-format.

System.IO.Compression.Deflate and zlib are reportedly not interoperable.

If you need to handle zip files (you probably don't, but someone else might need this) you need to use SharpZipLib or another third-party library.

始于初秋 2024-07-12 10:05:26

我使用 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 压缩的同一文件之间确实存在差异(可能是其他人所说的标头信息)在此线程中)。 然而,这种差异在实践中似乎并不重要。

I've used GZipStream to compress the output from the .NET XmlSerializer and it has worked perfectly fine to decompress the result with gunzip (in cygwin), winzip and another GZipStream.

For reference, here's what I did in code:

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);
}

Then, to decompress in 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);
}

Using the 'file' utility in cygwin reveals that there is indeed a difference between the same file compressed with GZipStream and with GNU GZip (probably header information as others has stated in this thread). This difference, however, seems to not matter in practice.

守不住的情 2024-07-12 10:05:26

gzip 是 deflate + 一些页眉/页脚数据,例如校验和和长度等。因此,它们不兼容,因为一种方法可以使用来自另一种方法的流,但它们采用相同的压缩算法。

gzip is deflate + some header/footer data, like a checksum and length, etc. So they're not compatible in the sense that one method can use a stream from the other, but they employ the same compression algorithm.

鸠魁 2024-07-12 10:05:26

他们只是使用 zlib 或 deflate 算法压缩数据,但不提供某些特定文件格式的输出。 这意味着,如果您将流按原样存储到硬盘驱动器,您很可能无法使用某些应用程序(gzip 或 winrar)打开它,因为文件头(幻数等)不包含在流中,您应该你自己写。

They just compressing the data using zlib or deflate algorithms , but does not provide the output for some specific file format. This means that if you store the stream as-is to the hard drive most probably you will not be able to open it using some application (gzip or winrar) because file headers (magic number, etc ) are not included in stream an you should write them yourself.

北斗星光 2024-07-12 10:05:26

从 .NET Framework 4.5 开始,System.IO.Compression.DeflateStream 类使用 zlib 库。

来自课程的 MSDN 文章

此类代表 Deflate 算法,它是无损文件压缩和解压缩的行业标准算法。 从 .NET Framework 4.5 开始,DeflateStream 类使用 zlib 库。 因此,它提供了更好的压缩算法,并且在大多数情况下,比早期版本的 .NET Framework 提供的压缩文件更小。

Starting from .NET Framework 4.5 the System.IO.Compression.DeflateStream class uses the zlib library.

From the class's MSDN article:

This class represents the Deflate algorithm, which is an industry-standard algorithm for lossless file compression and decompression. Starting with the .NET Framework 4.5, the DeflateStream class uses the zlib library. As a result, it provides a better compression algorithm and, in most cases, a smaller compressed file than it provides in earlier versions of the .NET Framework.

木槿暧夏七纪年 2024-07-12 10:05:26

我同意安德烈亚斯的观点。 您可能无法在外部工具中打开该文件,但如果该工具需要流,您也许可以使用它。 您还可以使用相同的压缩等级将文件放气。

I agree with andreas. You probably won't be able to open the file in an external tool, but if that tool expects a stream you might be able to use it. You would also be able to deflate the file back using the same compression class.

舞袖。长 2024-07-12 10:05:25

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

  • 两个标头字节(来自 RFC 1950 的 CMF 和 FLG),其值为 0x78 0x01
    • CM = 8 = 放气
    • CINFO = 7 = 32Kb 窗口
    • FCHECK = 1 = 此标头的校验和位
  • 位 C# 的输出DeflateStream
  • DeflateStream 输入数据的 Adler32 校验和,大端格式(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;
        }
    }
}

,仅此而已。

I ran into this issue with Git objects. In that particular case, they store the objects as deflated blobs with a Zlib header, which is documented in RFC 1950. You can make a compatible blob by making a file that contains:

  • Two header bytes (CMF and FLG from RFC 1950) with the values 0x78 0x01
    • CM = 8 = deflate
    • CINFO = 7 = 32Kb window
    • FCHECK = 1 = checksum bits for this header
  • The output of the C# DeflateStream
  • An Adler32 checksum of the input data to the DeflateStream, big-endian format (MSB first)

I made my own Adler implementation

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;
        }
    }
}

And that was pretty much it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文