• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

如何在c#中使用Zlib压缩与解压

c# 搞代码 4年前 (2022-01-09) 17次浏览 已收录 0个评论

介绍

近期用c#开发一个游戏的存档编辑工具需要用 Zlib 标准的 Deflate 算法对数据进行解压。 在 StackOverflow 上逛了一圈,发现 c# 比较常用到的方式是微软提供的 System.IO.Compression, zlib.net, 以及 ICSharpCode 的SharpZipLib。我简单的测试和包装了一下,便在这里分享一下成果以及我个人的看法。

System.IO.Compression

通常来说,使用c#开发时能用微软官方提供的工具就尽量用,一个是bug会比较少,维护会比较稳定。此外,官方提供的方案往往在优化上也会高于第三方工具。

虽然在.NET Framework 4.5 开始 System.IO.Compression.DeflateStream 也使用Zlib进行Deflate格式的压缩与解压了,但经过测试其压缩和解压结果与其他Zlib库有所不同.
仔细观察就会发现,用 DeflateStream 压缩后的数据开头比Zlib压缩的数据少两个字节,结尾比Zlib少四个字节; 这种输出格式叫做 Raw Deflate 。
经过查证,C# 提供的 DeflateStream只能压缩成或者解压这种Raw Deflate, 而不能处理标准的 Zlib Deflate 格式 (不过据说可以自己生成); 但反过来,Zlib 可以处理或生成这种不包含头尾数据的Raw Deflate.
当然,你也可以选择手动添加 header 和 trailer. 具体怎么添加可以阅读文末链接的参考资料,由于不是特别重要,我就偷个懒了。

以下是我使用此方法简单包装的压缩与解压数据的代码:

// 使用System.IO.Compression进行Deflate压缩
public static byte[] MicrosoftCompress(byte[] data)
{
    MemoryStream uncompressed = new MemoryStream(data); // 这里举例用的是内存中的数据;需要对文本进行压缩的话,使用 FileStream 即可
    MemoryStream compressed = new MemoryStream();
    DeflateStream deflateStream = new DeflateStream(compressed, CompressionMode.Compress); // 注意:这里第一个参数填写的是压缩后的数据应该被输出到的地方
    uncompressed.CopyTo(deflateStream); // 用 CopyTo 将需要压缩的数据一次性输入;也可以使用Write进行部分输入
    deflateStream.Close();  // 在Close中,会先后执行 Finish 和 Flush 操作。
    byte[] result = compressed.ToArray();
    return result;
}
// 使用System.IO.Compression进行Deflate解压
public static byte[] MicrosoftDecompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream(data);
    MemoryStream decompressed = new MemoryStream();
    DeflateStream deflateStream = new DeflateStream(compressed, CompressionMode.Decompress); // 注意: 这里第一个参数同样是填写压缩的数据,但是这次是作为输入的数据
    deflateStream.CopyTo(decompressed); 
    byte[] result = decompressed.ToArray();
    return result;
}

zlib.net

zlib.net是一个非常小体量的开源的第三方工具。经过本人有限的研究和了解,这个库其实更像是一个半成品,许多功能都不完善,不过优点在于非常轻巧,而且与c++端使用 boost::iostreams::zlib 效果相同。

以下是用 zlib.net 提供的 ZOutputStream 类来压缩数据的代码

public static byte[] ZLibDotnetCompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream();
    ZOutputStream outputStream = new ZOutputStream(compressed, 2); 
    outputStream.Write(data, 0, data.Length); // 这里采用的是用 Write 来写入需要压缩的数据;也可以采用和上面一样的方法
    outputStream.Close();
    byte[] result = compressed.ToArray();
    return result;
}

以下是用zlib.net 提供的 ZInputStream 类来解压数据的代码

public static byte[] ZLibDotnetDecompress(byte[] data, int size)
{
    MemoryStream compressed = new MemoryStream(data);
    ZInputStream <strong style="color:transparent">来源gaodai#ma#com搞@代~码$网</strong>inputStream = new ZInputStream(compressed);
    byte[] result = new byte[size];   // 由于ZInputStream 继承的是BinaryReader而不是Stream, 只能提前准备好输出的 buffer 然后用 read 获取定长数据。
    inputStream.read(result, 0, result.Length); // 注意这里的 read 首字母是小写
    return result;
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:如何在c#中使用Zlib压缩与解压
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址