首页 > 技术文章 > 【C#】依赖于SharpZipLib的Zip压缩工具类

zengyiqun 2014-05-14 19:21 原文

  上班第二天下班,课外作业,实现一个ZIP压缩的工具类.本来想用Package,但是写完了才发现不能解压其他工具压缩的zip包,比较麻烦,因此本工具类依赖了第三方的库(SharpZipLib  version 0.86.0 http://icsharpcode.github.io/SharpZipLib/),上午花了两个小时整理了下代码,mark下!

  

 1 /**
 2  * Class: ZIP压缩工具类
 3  * Reference: SharpZipLib  version 0.86.0 (http://icsharpcode.github.io/SharpZipLib/)
 4  * Author: Zengyq
 5  * Version: 1.0
 6  * Create Date: 2014-05-13
 7  * Modified Date: 2014-05-14
 8  */
 9 
10 /****************构造函数*************************/
11 ZipUtils()
12 ZipUtils(int compressionLevel)
13 
14 /****************方法列表*************************/
15 /// <summary>
16 /// 功能: ZIP方式压缩文件(压缩目录)
17 /// </summary>
18 /// <param name="dirPath">被压缩的文件夹夹路径</param>
19 /// <param name="zipFilePath">生成压缩文件的路径,缺省值:文件夹名+.zip</param>
20 /// <param name="msg">返回消息</param>
21 /// <returns>是否压缩成功</returns>
22 public bool ZipFolder(string dirPath, string zipFilePath, out string msg)
23 
24 /// <summary>
25 /// 功能:压缩文件指定文件
26 /// </summary>
27 /// <param name="filenames">要压缩文件的绝对路径</param>
28 /// <param name="zipFilePath">生成压缩文件的路径, 缺省值为随机数字串.zip</param>
29 /// <param name="msg">返回消息</param>
30 /// <returns>是否压缩成功</returns>
31 public bool ZipFiles(string[] filenames, string zipFilePath, out string msg)
32 
33 /// <summary>
34 /// 解压ZIP格式的文件。
35 /// </summary>
36 /// <param name="zipFilePath">压缩文件路径</param>
37 /// <param name="unZipDir">解压文件存放路径,缺省值压缩文件同一级目录下,跟压缩文件同名的文件夹</param>
38 /// <param name="msg">返回消息</param>
39 /// <returns>解压是否成功</returns>
40 public bool UnZipFile(string zipFilePath, string unZipDir, out string msg)
41 
42 /// <summary>
43 /// 解压指定ZIP文件到当前路径
44 /// </summary>
45 /// <param name="zipFilePath">ZIP文件绝对路径</param>
46 /// <param name="msg">返回消息</param>
47 /// <returns>解压是否成功</returns>
48 public bool UnZipFileToCurrentPath(string zipFilePath, out string msg)
49 
50 /****************调用样例*************************/
51 ZipUtils zu = new ZipUtils(); 
52 string msg = "";
53 zu.UnZipFileToCurrentPath(@"C:\Users\zengyiqun\Desktop\package1024.zip", out msg);

 

  类实现,没有采用静态类的形式,看了某博客用了out作为msg不懂会不会用到,先这样了,以下是实现类:

  1 /**
  2  * Class: ZIP压缩工具类
  3  * Reference: SharpZipLib  version 0.86.0 (http://icsharpcode.github.io/SharpZipLib/)
  4  * Author: Zengyq
  5  * Version: 1.0
  6  * Create Date: 2014-05-13
  7  * Modified Date: 2014-05-14
  8  */
  9 
 10 using ICSharpCode.SharpZipLib.Zip;
 11 using System;
 12 using System.IO;
 13 
 14 public class ZipUtils
 15 {
 16     //缓存大小
 17     private int BufferSize;
 18 
 19     //压缩率 0(无压缩)-9(压缩率最高)
 20     private int CompressionLevel;
 21 
 22     //压缩是用于存放压缩路径
 23     private string CompressPath;
 24 
 25 
 26     #region 构造函数
 27     /// <summary>
 28     /// 无参构造
 29     /// </summary>
 30     public ZipUtils()
 31     {
 32         this.BufferSize = 4096;
 33         this.CompressionLevel = 9;
 34     }
 35 
 36     /// <summary>
 37     /// 带参数构造
 38     /// </summary>
 39     /// <param name="compressionLevel">0(无压缩)-9(压缩率最高)</param>
 40     public ZipUtils(int compressionLevel)
 41     {
 42         this.BufferSize = 4096;
 43         this.CompressionLevel = compressionLevel;
 44     }
 45     #endregion
 46 
 47     #region 压缩方法
 48     /// <summary>
 49     /// 功能: ZIP方式压缩文件(压缩目录)
 50     /// </summary>
 51     /// <param name="dirPath">被压缩的文件夹夹路径</param>
 52     /// <param name="zipFilePath">生成压缩文件的路径,缺省值:文件夹名+.zip</param>
 53     /// <param name="msg">返回消息</param>
 54     /// <returns>是否压缩成功</returns>
 55     public bool ZipFolder(string dirPath, string zipFilePath, out string msg)
 56     {
 57         this.CompressPath = dirPath;
 58         //判断目录是否为空
 59         if (dirPath == string.Empty)
 60         {
 61             msg = "The Folder is empty";
 62             return false;
 63         }
 64 
 65         //判断目录是否存在
 66         if (!Directory.Exists(dirPath))
 67         {
 68             msg = "The Folder is not exists";
 69             return false;
 70         }
 71 
 72         //压缩文件名为空时使用 文件夹名.zip
 73         if (zipFilePath == string.Empty || zipFilePath == null)
 74         {
 75             if (dirPath.EndsWith("//"))
 76             {
 77                 dirPath = dirPath.Substring(0, dirPath.Length - 1);
 78             }
 79             zipFilePath = dirPath + ".zip";
 80         }
 81 
 82         try
 83         {
 84             using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFilePath)))
 85             {
 86                 s.SetLevel(this.CompressionLevel);
 87                 ZipDirectory(dirPath, s);//压缩目录,包含子目录
 88                 s.Finish();
 89                 s.Close();
 90             }
 91         }
 92         catch (Exception ex)
 93         {
 94             msg = ex.Message;
 95             return false;
 96         }
 97 
 98         msg = "Success";
 99         return true;
100     }//end function
101 
102     /// <summary>
103     /// 压缩文件指定文件
104     /// </summary>
105     /// <param name="filenames">要压缩文件的绝对路径</param>
106     /// <param name="zipFilePath">生成压缩文件的路径, 缺省值为当前时间.zip</param>
107     /// <param name="msg">返回消息</param>
108     /// <returns>是否压缩成功</returns>
109     public bool ZipFiles(string[] filenames, string zipFilePath, out string msg)
110     {
111         msg = "";
112         if (filenames.Length == 0)
113         {
114             msg = "No File Selected";
115             return false;
116         }
117 
118         //压缩文件名为空时使用 文件夹名.zip
119         if (zipFilePath == string.Empty || zipFilePath == null)
120         {
121             zipFilePath = System.Environment.CurrentDirectory + "\\" + DateTime.Now.ToFileTimeUtc().ToString() + ".zip";
122         }
123 
124         try
125         {
126             using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFilePath)))
127             {
128                 s.SetLevel(this.CompressionLevel);
129                 ZipFilesAndDirectory(filenames,s);
130                 s.Finish();
131                 s.Close();
132             }//end using
133         }
134         catch (Exception ex)
135         {
136             msg = ex.Message;
137             return false;
138         }
139 
140         msg = "Success";
141         return true;
142     }
143 
144     #endregion
145 
146     #region 解压方法
147     /// <summary>
148     /// 解压ZIP格式的文件。
149     /// </summary>
150     /// <param name="zipFilePath">压缩文件路径</param>
151     /// <param name="unZipDir">解压文件存放路径,缺省值压缩文件同一级目录下,跟压缩文件同名的文件夹</param>
152     /// <param name="msg">返回消息</param>
153     /// <returns>解压是否成功</returns>
154     public bool UnZipFile(string zipFilePath, string unZipDir, out string msg)
155     {
156         msg = "";
157 
158         //判读路径是否为空
159         if (zipFilePath == string.Empty || zipFilePath == null)
160         {
161             msg = "ZipFile No Selected";
162             return false;
163         }
164 
165         //判读文件是否存在
166         if (!File.Exists(zipFilePath))
167         {
168             msg = "ZipFile No Exists";
169             return false;
170         }
171         //解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹
172         if (unZipDir == string.Empty || unZipDir == null)
173         {
174             unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
175         }
176 
177         if (!unZipDir.EndsWith("//")) 
178         {
179             unZipDir += "//";
180         }
181             
182         if (!Directory.Exists(unZipDir))
183         {
184             Directory.CreateDirectory(unZipDir);
185         }
186 
187         try
188         {
189             using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
190             {
191 
192                 ZipEntry theEntry;
193                 while ((theEntry = s.GetNextEntry()) != null)
194                 {
195                     string directoryName = Path.GetDirectoryName(theEntry.Name);
196                     string fileName = Path.GetFileName(theEntry.Name);
197                     if (directoryName.Length > 0)
198                     {
199                         Directory.CreateDirectory(unZipDir + directoryName);
200                     }
201                     if (!directoryName.EndsWith("//"))
202                     { 
203                         directoryName += "//";
204                     }
205                     if (fileName != String.Empty && fileName != null)
206                     {
207                         using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
208                         {
209                             CopyStream(s, streamWriter);
210                         }
211                     }
212                 }//end while
213             }//end using
214         }
215         catch (Exception ex)
216         {
217             msg = ex.Message;
218             return false;
219         }
220 
221         msg = "UnZip Success ! ";
222         return true;
223     }//end function
224 
225     /// <summary>
226     /// 解压指定ZIP文件到当前路径
227     /// </summary>
228     /// <param name="zipFilePath">ZIP文件绝对路径</param>
229     /// <param name="msg">返回消息</param>
230     /// <returns>解压是否成功</returns>
231     public bool UnZipFileToCurrentPath(string zipFilePath, out string msg)
232     {
233         msg = "";
234 
235         //判读路径是否为空
236         if (zipFilePath == string.Empty || zipFilePath == null)
237         {
238             msg = "ZipFile No Selected";
239             return false;
240         }
241 
242         //判读文件是否存在
243         if (!File.Exists(zipFilePath))
244         {
245             msg = "ZipFile No Exists";
246             return false;
247         }
248         //解压到当前目录
249         string unZipDir = zipFilePath.Substring(0, zipFilePath.LastIndexOf(@"\"));
250 
251         if (!unZipDir.EndsWith("//"))
252         {
253             unZipDir += "//";
254         }
255 
256         if (!Directory.Exists(unZipDir))
257         {
258             Directory.CreateDirectory(unZipDir);
259         }
260 
261         try
262         {
263             using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
264             {
265                 ZipEntry theEntry;
266                 while ((theEntry = s.GetNextEntry()) != null)
267                 {
268                     string directoryName = Path.GetDirectoryName(theEntry.Name);
269                     string fileName = Path.GetFileName(theEntry.Name);
270                     if (directoryName.Length > 0)
271                     {
272                         Directory.CreateDirectory(unZipDir + directoryName);
273                     }
274                     if (!directoryName.EndsWith("//"))
275                     {
276                         directoryName += "//";
277                     }
278                     if (fileName != String.Empty && fileName != null)
279                     {
280                         using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
281                         {
282                             CopyStream(s, streamWriter);
283                         }
284                     }
285                 }//end while
286             }//end using
287         }
288         catch (Exception ex)
289         {
290             msg = ex.Message;
291             return false;
292         }
293 
294         msg = "UnZip Success ! ";
295         return true;
296     }//end function
297 
298     #endregion
299 
300     #region 内部方法
301 
302     /// <summary>
303     /// 内部类:递归压缩目录
304     /// </summary>
305     /// <param name="dirPath"></param>
306     /// <param name="s"></param>
307     private void ZipDirectory(string dirPath, ZipOutputStream s)
308     {
309         string[] filenames = Directory.GetFiles(dirPath);
310         byte[] buffer = new byte[this.BufferSize];
311         foreach (string file in filenames)
312         {
313             //处理相对路径问题
314             ZipEntry entry = new ZipEntry(file.Replace(this.CompressPath + "\\", String.Empty));
315             //设置压缩时间
316             entry.DateTime = DateTime.Now;
317 
318             s.PutNextEntry(entry);
319             using (FileStream fs = File.OpenRead(file))
320             {
321                 CopyStream(fs, s);
322             }
323         }
324 
325         //递归处理子目录
326         DirectoryInfo di = new DirectoryInfo(dirPath);
327         foreach (DirectoryInfo subDi in di.GetDirectories())
328         {
329             ZipDirectory(subDi.FullName, s);
330         }
331 
332     }//end function
333 
334     /// <summary>
335     /// 
336     /// </summary>
337     /// <param name="filenames"></param>
338     /// <param name="s"></param>
339     private void ZipFilesAndDirectory(string[] filenames, ZipOutputStream s)
340     {
341         byte[] buffer = new byte[this.BufferSize];
342         foreach (string file in filenames)
343         {
344             //当时文件的时候
345             if (System.IO.File.Exists(file))
346             {
347                 ZipEntry entry = new ZipEntry(Path.GetFileName(file));
348                 entry.DateTime = DateTime.Now;
349                 s.PutNextEntry(entry);
350                 using (FileStream fs = File.OpenRead(file))
351                 {
352                     CopyStream(fs, s);
353                 }
354             }
355 
356             //当时目录的时候
357             if(System.IO.Directory.Exists(file))
358             {
359                 this.CompressPath = file.Replace("\\" + Path.GetFileName(file),String.Empty);
360                 ZipDirectory(file, s);
361             }
362 
363         }
364 
365        
366     }
367 
368 
369 
370     /// <summary>
371     /// 按块复制
372     /// </summary>
373     /// <param name="source">源Stream</param>
374     /// <param name="target">目标Stream</param>
375     private void CopyStream(Stream source, Stream target)
376     {
377         byte[] buf = new byte[this.BufferSize];
378         int byteRead = 0;
379         while ((byteRead = source.Read(buf, 0, this.BufferSize)) > 0)
380         {
381             target.Write(buf, 0, byteRead);
382         }
383 
384     }
385     #endregion
386 
387 }//end class

  代码风格还请大家轻喷,在.net程序员面前是个非主流java程序员,在java程序员面前是个非主流.net程序员。将以上工具类封装成了dll可以直接引用。

  附件:ZipUtils.rar

1 ZipUtils.rar
2     -src
3         -ZipUtils.cs
4     -dll
5         -SharpZipLib.dll
6         -ZipUtilsLib.dll

 

推荐阅读