广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >如何在c#中使用Zlib压缩与解压
  • 892
分享到

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

2024-04-02 19:04:59 892人浏览 泡泡鱼
摘要

目录介绍System.io.Compressionzlib.netSharpZipLib速度对比总结参考与延申关于Zlib关于 Deflate 和 Raw Deflate关于CSha

介绍

近期用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 inputStream = new ZInputStream(compressed);
    byte[] result = new byte[size];   // 由于ZInputStream 继承的是BinaryReader而不是Stream, 只能提前准备好输出的 buffer 然后用 read 获取定长数据。
    inputStream.read(result, 0, result.Length); // 注意这里的 read 首字母是小写
    return result;
}

你需要通过read来获取解压后的数据,同时你要在调用其解压的方法时提前提供好外部的buffer用于储存输出的数据,这个buffer的大小就是一个问题了。
如果打算使用这个的话,建议除了储存压缩的数据以外,在不会被压缩的位置添加压缩前大小的数据。

但总体来说,个人不建议使用这个工具。

https://GitHub.com/zyborg/zlib.net
Http://www.componentace.com/zlib_.NET.htm

SharpZipLib

我最终选择使用的是 SharpZipLib. (编辑:当时没做速度测试,且我需要解压的文件不是太大,速度也不是很重要,否则的话不推荐选择这个方案。。。)

ICSharpCode 不愧是开发了 ILSpy 的团队,SharpZipLib 在提供强大的功能的同时,使用也很方便。限于主题,这里只讨论用 Deflate 格式来压缩数据流。

简单来说,你需要做的就是通过 DeflaterOutputStream 来压缩,InflaterInputStream 来解压,而除了压缩和解压分在两个不同的类以外,其他的操作方式和 System.IO.Compression.DeflateStream 可以做到完全一样。
而且其压缩和解压的结果和直接使用Zlib官方的库一模一样,开发辅助其他程序的工具时不用担心头尾数据的问题,算是非常省事了。

以下是我使用该方案简单包装的方法:


public static byte[] SharpZipLibCompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream();
    DeflaterOutputStream outputStream = new DeflaterOutputStream(compressed);
    outputStream.Write(data, 0, data.Length);
    outputStream.Close();
    return compressed.ToArray();
}

public static byte[] SharpZipLibDecompress(byte[] data)
{
    MemoryStream compressed = new MemoryStream(data);
    MemoryStream decompressed = new MemoryStream();
    InflaterInputStream inputStream = new InflaterInputStream(compressed);
    inputStream.CopyTo(decompressed);
    return decompressed.ToArray();
}

速度对比

为了对比几种方法在压缩与解压效率上的优劣,我准备了两组数据做了一个简单的测试。

第一组为短数据,是一个简单的字符串 "this is just a string for testing, see how this compression thing works."
第二组为长数据,是在网上下载到的英文版的 《冰与火之歌:权利的游戏》txt文本,大小约1.7mb。

我分别用每个方法压缩和解压短数据1000次,长数据100次, 最终的结果如下:


Length of Short Data: 144
Length of Long Data: 1685502

============================================
Compress and decompress with Microsoft Zlib Compression (1000 times): 54
Compress and decompress with Microsoft Zlib Compression (long data 100 times): 7924

============================================
Compress and decompress with Zlib.net Compression (1000 times): 254
Compress and decompress with Zlib.net Compression (long data 100 times): 9924

============================================
Compress and decompress with SharpZipLib Compression (1000 times): 442
Compress and decompress with SharpZipLib Compression (long data 100 times): 26782

显而易见的,无论是长数据还是短数据的压缩与解压,System.IO.Compression中提供的方法都优于另外两种方法。

Zlib.net在速度上的劣势不明显,而同样的算法SharpZipLib要花两到三倍的时间。

总结

最终,不出所料的,微软官方提供的 System.IO.Compression 中的方法在速度上有着明显的优势;虽然不会提供Deflate的头尾信息,但可以想办法自己生成,而且这一缺点基本上是可以完全忽略的。 Zlib.net 虽然在速度上表现也不错,同时也会生成Deflate压缩的头尾信息,但因为其包装比较潦草,使用起来相对不方便。而 SharpZipLib 很可惜,虽然其他各方面都很方便,但速度上的缺陷相当致命,只能在一定需要 Deflate 而非 RawDeflate 或者使用的.Net Framework早于4.5的时候(且运行中时间消耗不重要)偷懒的用一用了。

参考与延申

关于Zlib

https://zlib.net/

关于 Deflate 和 Raw Deflate

https://stackoverflow.com/questions/37845440/net-deflatestream-vs-linux-zlib-difference
https://www.ietf.org/rfc/rfc1950.txt
https://www.ietf.org/rfc/rfc1951.txt

关于CSharp System.IO.Compression.DeflateStream

https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.deflatestream?view=net-5.0

开发者之一 Mark Adler 在 StackOverflow 上的回答

deflate 和 compress 函数的区别

https://stackoverflow.com/questions/10166122/zlib-differences-between-the-deflate-and-compress-functions/10168441#10168441

如何手动添加 header 和 trailer
https://stackoverflow.com/questions/39939869/data-fORMat-for-system-io-compression-deflatestream

以上就是如何再c#中使用Zlib压缩与解压的详细内容,更多关于c#使用Zlib压缩与解压的资料请关注编程网其它相关文章!

--结束END--

本文标题: 如何在c#中使用Zlib压缩与解压

本文链接: https://www.lsjlt.com/news/124765.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何在c#中使用Zlib压缩与解压
    目录介绍System.IO.Compressionzlib.netSharpZipLib速度对比总结参考与延申关于Zlib关于 Deflate 和 Raw Deflate关于CSha...
    99+
    2022-11-12
  • 怎么在java中利用压缩流实现压缩与解压
    本篇文章给大家分享的是有关怎么在java中利用压缩流实现压缩与解压,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程...
    99+
    2023-06-14
  • python用模块zlib压缩与解压字符串和文件的方法
    python中zlib模块是用来压缩或者解压缩数据,以便保存和传输。它是其他压缩工具的基础。下面来一起看看python用模块zlib压缩与解压字符串和文件的方法。话不多说,直接来看示例代码。 例子1:压缩与...
    99+
    2022-06-04
    字符串 模块 文件
  • C#使用SharpZipLib压缩解压文件
    一、介绍 SharpZipLib是一个完全由C#编写的ZIP,GZIP,Tar和BZIP2 Library,可以方便的支持这几种格式的压缩和解压缩。 https://github.c...
    99+
    2022-11-13
  • 如何在C#中压缩和解压rar、zip文件
    这期内容当中小编将会给大家带来有关如何在C#中压缩和解压rar、zip文件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在C#.NET中压缩解压rar文件rar格式是一种具有专利文件的压缩格式,是一种商业...
    99+
    2023-06-15
  • C# 使用原生 System.IO.Compression 实现 zip 的压缩与解压
    zip 是一个非常常见的压缩包格式,本文主要用于说明如何使用代码 文件或文件夹压缩为 zip压缩包及其解压操作,我们采用的是 微软官方的实现,所以也不需要安装第三方的组件包。 使用的...
    99+
    2022-11-13
  • 如何在PHP中使用压缩和解压函数
    PHP作为一种流行的编程语言,提供了许多处理文件和数据的功能。其中包括压缩和解压文件的函数。这些函数可以让开发者在PHP中轻松地压缩和解压数据,从而减少文件大小并提高传输效率。本文将介绍如何在PHP中使用压缩和解压函数。一、压缩文件在PHP...
    99+
    2023-05-19
    压缩 PHP 解压函数
  • Linux如何使用命令进行压缩与解压缩操作
    这篇文章将为大家详细讲解有关Linux如何使用命令进行压缩与解压缩操作,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在学习压缩和解压缩之前。首先,要了解一下打包、压缩、解压缩的基本概念。打包文件:一看到 ...
    99+
    2023-06-09
  • Android应用中如何对文件进行压缩与解压缩
    Android应用中如何对文件进行压缩与解压缩?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。使用场景当我们在应用的Assets目录中需要加入文件时,可以直接将源文件放入,但这样...
    99+
    2023-05-31
    android roi
  • 如何在Linux中使用Gzip压缩和解压文件
    这篇文章主要介绍“如何在Linux中使用Gzip压缩和解压文件”,在日常操作中,相信很多人在如何在Linux中使用Gzip压缩和解压文件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何在Linux中使用Gz...
    99+
    2023-06-13
  • java如何解压与压缩文件夹
    这篇文章将为大家详细讲解有关java如何解压与压缩文件夹,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。注意:JDK7支持设置编码设置编码格式 zipFile,zipInputStream,zipOutpu...
    99+
    2023-05-31
    java
  • Java如何实现ZIP压缩与解压
    Java如何实现ZIP压缩与解压,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。程序实现了ZIP压缩。共分为2部分 : 压缩(compression)与解压(de...
    99+
    2023-06-17
  • 如何在Java中利用zip实现压缩和解压缩
    这篇文章主要介绍了如何在Java中利用zip实现压缩和解压缩,编程网小编觉得不错,现在分享给大家,也给大家做个参考,一起跟随编程网小编来看看吧!Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系统和...
    99+
    2023-06-06
  • 在java项目中使用ant包如何实现压缩和解压缩
    在java项目中使用ant包如何实现压缩和解压缩?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。java ant包中的org.apache.tools.zip实现...
    99+
    2023-05-31
    java ant ava
  • Redis如何实现数据压缩与解压缩功能
    Redis是一款高性能的内存数据库,常用于缓存和数据存储。在数据存储方面,Redis提供了压缩和解压缩功能,可以有效地节省内存空间,提高数据存储和传输效率。本文将介绍Redis如何实现数据压缩和解压缩功能,并给出具体代码示例。Redis中的...
    99+
    2023-11-07
    redis 数据压缩 解压缩
  • Win10如何使用自带压缩、解压zip压缩文件功能
      Windows系统自带不少工具,到了Win10,好用的功能依然保留,比如压缩/解压zip压缩文件的功能。压缩文件能为系统节省空间,这一功能必不可少。Win10如何使用压缩/解压zip压缩文件功能?   Win10压缩...
    99+
    2023-06-10
    Win10 压缩 功能 自带 压缩文件
  • tar压缩解压缩命令怎么在Linux系统中使用
      tar,是Linux系统的一个命令,非常好用!如果你对tar命令不甚了解的话,可以看看小编为大家整理的tar压缩解压缩命令详解。01root@ubuntu:~# tar --help02用法: tar [选项...] [FILE]......
    99+
    2023-06-07
  • 如何使用Node的内置模块zlib进行gzip压缩
    这篇文章主要介绍了如何使用Node的内置模块zlib进行gzip压缩的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何使用Node的内置模块zlib进行gzip压缩文章都会有所...
    99+
    2022-10-19
  • Linux中如何打包压缩解压
    这篇文章将为大家详细讲解有关Linux中如何打包压缩解压,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容如下所述:tar命令解包:tar zxvf FileName.tar打包:tar czvf F...
    99+
    2023-06-09
  • 使用Java怎么对字符串进行压缩与解压缩
    本篇文章给大家分享的是有关使用Java怎么对字符串进行压缩与解压缩,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java可以用来干什么Java主要应用于:1. web开发;2....
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作