欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 利用SharpZipLib生成压缩包

程序员文章站 2022-05-25 14:38:43
本文通过一个简单的小例子简述SharpZipLib压缩文件的常规用法,仅供学习分享使用,如有不足之处,还请指正。 ......

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

什么是sharpziplib ?

sharpziplib是一个c#的类库,主要用来解压缩zip,gzip,bzip2,tar等格式,是以托管程序集的方式实现,可以方便的应用于其他的项目之中。

在工程中引用sharpziplib

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

C# 利用SharpZipLib生成压缩包

sharpziplib的关键类结构图

如下所示:

C# 利用SharpZipLib生成压缩包

涉及知识点:

  • zipoutputstream 压缩输出流,将文件一个接一个的写入压缩文档,此类不是线程安全的。
  • putnextentry 开始一个新的zip条目,zipoutputstream中的方法。
  • zipentry 一个zip文件中的条目,可以理解为压缩包里面的一个文件夹/文件。
  • zipinputstream 解压缩输出流,从压缩包中一个接一个的读出文档。
  • getnextentry 读出zip条目,zipinputstream中的方法。

示例效果图:

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

C# 利用SharpZipLib生成压缩包

核心代码

C# 利用SharpZipLib生成压缩包
  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, 0, 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, 0, 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(1);
 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(6);
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, 0, 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(6);
157 
158                 zipstream.write(buffer, 0, 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(1);
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 = 2048;
280                         byte[] data = new byte[size];
281                         while (true)
282                         {
283                             size = zipstream.read(data, 0, data.length);
284                             if (size > 0)
285                                 fs.write(data, 0, 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(1);
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 }
view code

备注

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

关于sharpziplib的的api文档,可参看链接

关于源码下载链接