本文通过一个简单的小例子简述SharpZipLib压缩文件的常规用法,仅供学习分享使用,如有不足之处,还请指正。

什么是SharpZipLib ?

SharpZipLib是一个C#的类库,主要用来解压缩Zip,GZip,BZip2,Tar等格式,是以托管程序集的方式实现,可以方便的应用于其他的项目之中。

在工程中引用SharpZipLib

在项目中,点击项目名称右键-->管理NuGet程序包,打开NuGet包管理器窗口,进行搜索下载即可,如下图所示:

SharpZipLib的关键类结构图

如下所示:

涉及知识点:

  • ZipOutputStream 压缩输出流,将文件一个接一个的写入压缩文档,此类不是线程安全的。
  • PutNextEntry 开始一个新的ZIP条目,ZipOutputStream中的方法。
  • ZipEntry 一个ZIP文件中的条目,可以理解为压缩包里面的一个文件夹/文件。
  • ZipInputStream 解压缩输出流,从压缩包中一个接一个的读出文档。
  • GetNextEntry 读出ZIP条目,ZipInputStream中的方法。

示例效果图:

关于解压缩小例子的示例效果图,如下:

核心代码

  1. using ICSharpCode.SharpZipLib.Checksum;
  2. using ICSharpCode.SharpZipLib.Zip;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9.  
  10. namespace DemoZip
  11. {
  12. class ZipHelper
  13. {
  14. private string rootPath = string.Empty;
  15.  
  16. #region 压缩
  17.  
  18. /// <summary>
  19. /// 递归压缩文件夹的内部方法
  20. /// </summary>
  21. /// <param name="folderToZip">要压缩的文件夹路径</param>
  22. /// <param name="zipStream">压缩输出流</param>
  23. /// <param name="parentFolderName">此文件夹的上级文件夹</param>
  24. /// <returns></returns>
  25. private bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
  26. {
  27. bool result = true;
  28. string[] folders, files;
  29. ZipEntry ent = null;
  30. FileStream fs = null;
  31. Crc32 crc = new Crc32();
  32.  
  33. try
  34. {
  35. string entName = folderToZip.Replace(this.rootPath, string.Empty)+"/";
  36. //Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/")
  37. ent = new ZipEntry(entName);
  38. zipStream.PutNextEntry(ent);
  39. zipStream.Flush();
  40.  
  41. files = Directory.GetFiles(folderToZip);
  42. foreach (string file in files)
  43. {
  44. fs = File.OpenRead(file);
  45.  
  46. byte[] buffer = new byte[fs.Length];
  47. fs.Read(buffer, , buffer.Length);
  48. ent = new ZipEntry(entName + Path.GetFileName(file));
  49. ent.DateTime = DateTime.Now;
  50. ent.Size = fs.Length;
  51.  
  52. fs.Close();
  53.  
  54. crc.Reset();
  55. crc.Update(buffer);
  56.  
  57. ent.Crc = crc.Value;
  58. zipStream.PutNextEntry(ent);
  59. zipStream.Write(buffer, , buffer.Length);
  60. }
  61.  
  62. }
  63. catch
  64. {
  65. result = false;
  66. }
  67. finally
  68. {
  69. if (fs != null)
  70. {
  71. fs.Close();
  72. fs.Dispose();
  73. }
  74. if (ent != null)
  75. {
  76. ent = null;
  77. }
  78. GC.Collect();
  79. GC.Collect();
  80. }
  81.  
  82. folders = Directory.GetDirectories(folderToZip);
  83. foreach (string folder in folders)
  84. if (!ZipDirectory(folder, zipStream, folderToZip))
  85. return false;
  86.  
  87. return result;
  88. }
  89.  
  90. /// <summary>
  91. /// 压缩文件夹
  92. /// </summary>
  93. /// <param name="folderToZip">要压缩的文件夹路径</param>
  94. /// <param name="zipedFile">压缩文件完整路径</param>
  95. /// <param name="password">密码</param>
  96. /// <returns>是否压缩成功</returns>
  97. public bool ZipDirectory(string folderToZip, string zipedFile, string password)
  98. {
  99. bool result = false;
  100. if (!Directory.Exists(folderToZip))
  101. return result;
  102.  
  103. ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
  104. zipStream.SetLevel();
  105. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  106.  
  107. result = ZipDirectory(folderToZip, zipStream, "");
  108.  
  109. zipStream.Finish();
  110. zipStream.Close();
  111.  
  112. return result;
  113. }
  114.  
  115. /// <summary>
  116. /// 压缩文件夹
  117. /// </summary>
  118. /// <param name="folderToZip">要压缩的文件夹路径</param>
  119. /// <param name="zipedFile">压缩文件完整路径</param>
  120. /// <returns>是否压缩成功</returns>
  121. public bool ZipDirectory(string folderToZip, string zipedFile)
  122. {
  123. bool result = ZipDirectory(folderToZip, zipedFile, null);
  124. return result;
  125. }
  126.  
  127. /// <summary>
  128. /// 压缩文件
  129. /// </summary>
  130. /// <param name="fileToZip">要压缩的文件全名</param>
  131. /// <param name="zipedFile">压缩后的文件名</param>
  132. /// <param name="password">密码</param>
  133. /// <returns>压缩结果</returns>
  134. public bool ZipFile(string fileToZip, string zipedFile, string password)
  135. {
  136. bool result = true;
  137. ZipOutputStream zipStream = null;
  138. FileStream fs = null;
  139. ZipEntry ent = null;
  140.  
  141. if (!File.Exists(fileToZip))
  142. return false;
  143.  
  144. try
  145. {
  146. fs = File.OpenRead(fileToZip);
  147. byte[] buffer = new byte[fs.Length];
  148. fs.Read(buffer, , buffer.Length);
  149. fs.Close();
  150.  
  151. fs = File.Create(zipedFile);
  152. zipStream = new ZipOutputStream(fs);
  153. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  154. ent = new ZipEntry(Path.GetFileName(fileToZip));
  155. zipStream.PutNextEntry(ent);
  156. zipStream.SetLevel();
  157.  
  158. zipStream.Write(buffer, , buffer.Length);
  159.  
  160. }
  161. catch
  162. {
  163. result = false;
  164. }
  165. finally
  166. {
  167. if (zipStream != null)
  168. {
  169. zipStream.Finish();
  170. zipStream.Close();
  171. }
  172. if (ent != null)
  173. {
  174. ent = null;
  175. }
  176. if (fs != null)
  177. {
  178. fs.Close();
  179. fs.Dispose();
  180. }
  181. }
  182. GC.Collect();
  183. GC.Collect();
  184.  
  185. return result;
  186. }
  187.  
  188. /// <summary>
  189. /// 压缩文件
  190. /// </summary>
  191. /// <param name="fileToZip">要压缩的文件全名</param>
  192. /// <param name="zipedFile">压缩后的文件名</param>
  193. /// <returns>压缩结果</returns>
  194. public bool ZipFile(string fileToZip, string zipedFile)
  195. {
  196. bool result = ZipFile(fileToZip, zipedFile, null);
  197. return result;
  198. }
  199.  
  200. /// <summary>
  201. /// 压缩文件或文件夹
  202. /// </summary>
  203. /// <param name="fileToZip">要压缩的路径</param>
  204. /// <param name="zipedFile">压缩后的文件名</param>
  205. /// <param name="password">密码</param>
  206. /// <returns>压缩结果</returns>
  207. public bool Zip(string fileToZip, string zipedFile, string password)
  208. {
  209. bool result = false;
  210. if (Directory.Exists(fileToZip))
  211. {
  212. this.rootPath = Path.GetDirectoryName(fileToZip);
  213. result = ZipDirectory(fileToZip, zipedFile, password);
  214. }
  215. else if (File.Exists(fileToZip))
  216. {
  217. this.rootPath = Path.GetDirectoryName(fileToZip);
  218. result = ZipFile(fileToZip, zipedFile, password);
  219. }
  220. return result;
  221. }
  222.  
  223. /// <summary>
  224. /// 压缩文件或文件夹
  225. /// </summary>
  226. /// <param name="fileToZip">要压缩的路径</param>
  227. /// <param name="zipedFile">压缩后的文件名</param>
  228. /// <returns>压缩结果</returns>
  229. public bool Zip(string fileToZip, string zipedFile)
  230. {
  231. bool result = Zip(fileToZip, zipedFile, null);
  232. return result;
  233.  
  234. }
  235.  
  236. #endregion
  237.  
  238. #region 解压
  239.  
  240. /// <summary>
  241. /// 解压功能(解压压缩文件到指定目录)
  242. /// </summary>
  243. /// <param name="fileToUnZip">待解压的文件</param>
  244. /// <param name="zipedFolder">指定解压目标目录</param>
  245. /// <param name="password">密码</param>
  246. /// <returns>解压结果</returns>
  247. public bool UnZip(string fileToUnZip, string zipedFolder, string password)
  248. {
  249. bool result = true;
  250. FileStream fs = null;
  251. ZipInputStream zipStream = null;
  252. ZipEntry ent = null;
  253. string fileName;
  254.  
  255. if (!File.Exists(fileToUnZip))
  256. return false;
  257.  
  258. if (!Directory.Exists(zipedFolder))
  259. Directory.CreateDirectory(zipedFolder);
  260.  
  261. try
  262. {
  263. zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));
  264. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  265. while ((ent = zipStream.GetNextEntry()) != null)
  266. {
  267. if (!string.IsNullOrEmpty(ent.Name))
  268. {
  269. fileName = Path.Combine(zipedFolder, ent.Name);
  270. fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi
  271.  
  272. if (fileName.EndsWith("\\"))
  273. {
  274. Directory.CreateDirectory(fileName);
  275. continue;
  276. }
  277.  
  278. fs = File.Create(fileName);
  279. int size = ;
  280. byte[] data = new byte[size];
  281. while (true)
  282. {
  283. size = zipStream.Read(data, , data.Length);
  284. if (size > )
  285. fs.Write(data, , data.Length);
  286. else
  287. break;
  288. }
  289. }
  290. }
  291. }
  292. catch
  293. {
  294. result = false;
  295. }
  296. finally
  297. {
  298. if (fs != null)
  299. {
  300. fs.Close();
  301. fs.Dispose();
  302. }
  303. if (zipStream != null)
  304. {
  305. zipStream.Close();
  306. zipStream.Dispose();
  307. }
  308. if (ent != null)
  309. {
  310. ent = null;
  311. }
  312. GC.Collect();
  313. GC.Collect();
  314. }
  315. return result;
  316. }
  317.  
  318. /// <summary>
  319. /// 解压功能(解压压缩文件到指定目录)
  320. /// </summary>
  321. /// <param name="fileToUnZip">待解压的文件</param>
  322. /// <param name="zipedFolder">指定解压目标目录</param>
  323. /// <returns>解压结果</returns>
  324. public bool UnZip(string fileToUnZip, string zipedFolder)
  325. {
  326. bool result = UnZip(fileToUnZip, zipedFolder, null);
  327. return result;
  328. }
  329.  
  330. #endregion
  331. }
  332. }

备注

关于生成压缩的方法还有很多,如通过命令行调用winrar的执行文件,SharpZipLib只是方法之一。

关于SharpZipLib的的API文档,可参看链接

关于源码下载链接

C# 利用SharpZipLib生成压缩包的更多相关文章

  1. C# DateTime的11种构造函数 [Abp 源码分析]十五、自动审计记录 .Net 登陆的时候添加验证码 使用Topshelf开发Windows服务、记录日志 日常杂记——C#验证码 c#_生成图片式验证码 C# 利用SharpZipLib生成压缩包 Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库

    C# DateTime的11种构造函数   别的也不多说没直接贴代码 using System; using System.Collections.Generic; using System.Glob ...

  2. 利用Swashbuckle生成Web API Help Pages

    利用Swashbuckle生成Web API Help Pages 这系列文章是参考了.NET Core文档和源码,可能有人要问,直接看官方的英文文档不就可以了吗,为什么还要写这些文章呢? 原因如下: ...

  3. Spring事务管理----声明式:利用TransactionProxyFactoryBean生成事务代理

    通常建议采用声明式事务管理.声明式事务管理的优势非常明显:代码中无需关于关注事务逻辑,让spring声明式事务管理负责事务逻辑,声明式事务管理无需与具体的事务逻辑耦合,可以方便地在不同事务逻辑之间切换 ...

  4. 利用JAVA生成二维码

    本文章整理于慕课网的学习视频<JAVA生成二维码>,如果想看视频内容请移步慕课网. 维基百科上对于二维码的解释. 二维条码是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图 ...

  5. 学习笔记:利用GDI+生成简单的验证码图片

    学习笔记:利用GDI+生成简单的验证码图片 /// <summary> /// 单击图片时切换图片 /// </summary> /// <param name=&quo ...

  6. (喷血分享)利用.NET生成数据库表的创建脚本,类似SqlServer编写表的CREATE语句

    (喷血分享)利用.NET生成数据库表的创建脚本,类似SqlServer编写表的CREATE语句 在我们RDIFramework.NET代码生成器中,有这样一个应用,就是通过数据库表自动生成表的CREA ...

  7. (Unity)Unity自定义Debug日志文件,利用VS生成Dll文件并使用Dotfuscated进展混淆,避免被反编译

    Unity自定义Debug日志文件,利用VS生成Dll文件并使用Dotfuscated进行混淆,避免被反编译. 1.打开VS,博主所用版本是Visual Studio 2013. 2.新建一个VC项目 ...

  8. JSP利用freemarker生成基于word模板的word文档

    利用freemarker生成基于word模板的word文档 freemarker简介 FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器 ...

  9. 利用FFmpeg生成视频缩略图 2.1.6

    利用FFmpeg生成视频缩略图 1.下载FFmpeg文件包,解压包里的\bin\下的文件解压到 D:\ffmpeg\ 目录下. 下载地址 http://ffmpeg.zeranoe.com/build ...

随机推荐

  1. 中间人攻击——ARP欺骗的原理、实战及防御

    ​ 1.1 什么是网关 首先来简单解释一下什么是网关,网关工作在OSI七层模型中的传输层或者应用层,用于高层协议的不同网络之间的连接,简单地说,网关就好比是一个房间通向另一个房间的一扇门. 1.2 A ...

  2. [Swift]LeetCode482. 密钥格式化 | License Key Formatting

    You are given a license key represented as a string S which consists only alphanumeric character and ...

  3. [Swift]LeetCode677. 键值映射 | Map Sum Pairs

    Implement a MapSum class with insert, and sum methods. For the method insert, you'll be given a pair ...

  4. Python档案袋(线程 )

    Python的进程和线程是使用的操作系统的原生线程和进程,其是去调用操作系统的相应接口实现 进程:之间不可直接共享数据,是资源的集合,进程必须有一个线程 线程:基于进程,之间可直接共享数据,可执行,只 ...

  5. 10 个深恶痛绝的 Java 异常。。

    异常是 Java 程序中经常遇到的问题,我想每一个 Java 程序员都讨厌异常,一 个异常就是一个 BUG,就要花很多时间来定位异常问题. 什么是异常及异常的分类请看这篇文章:一张图搞清楚 Java ...

  6. .NET Core实战项目之CMS 第八章 设计篇-内容管理极简设计全过程

    写在前面 上一篇文章中我带着大家进行了权限部分的极简设计,也仅仅是一个基本的权限设计.不过你完全可以基于这套权限系统设计你的更复杂的权限系统,当然更复杂的权限系统要根据你的业务来进行,因为任何脱离实际 ...

  7. JAVA日志的前世今生

    这世界上很多事情,看起来就像彩虹一样炫目而神奇,实际上背后蕴含着随处可见的原理.就好像静儿几年前买过一件超贵的防辐射服,当时销售人员把手机严严实实的包在防辐射服里,然后让我打电话测试,果然没有信号. ...

  8. 《两地书》--Kubernetes(K8s)基础知识(docker容器技术)

    大家都知道历史上有段佳话叫“司马相如和卓文君”.“皑如山上雪,皎若云间月”.卓文君这么美,却也抵不过多情女儿薄情郎. 司马相如因一首<子虚赋>得汉武帝赏识,飞黄腾达之后便要与卓文君“故来相 ...

  9. C#2.0导航

    主要特性 泛型 类型和方法的参数化 可空类型 值类型可为null 委托 更简化的方式 迭代器 简单的foreach,不简单的状态机

  10. MHA非root用户搭建测试

    最近一直在瞎搬砖,最大的感触是运维工作难做.不过废话不多说,最近被分配了一项比较有意思的task,尝试着非root用户搭建MHA并测试下能否成功漂移,以下是两天测试和文档编写的成果,分享给各位看客,欢 ...