【C#公共幫助類】ZipHelper 壓縮和解壓幫助類,經過實戰總結出來的代碼,
關於本文檔的說明
本文檔基於ICSharpCode.SharpZipLib.dll的封裝,常用的解壓和壓縮方法都已經涵蓋在內,都是經過項目實戰積累下來的
歡迎傳播分享,必須保持原作者的信息,但禁止將該文檔直接用於商業盈利。
本人自從幾年前走上編程之路,一直致力於收集和總結出好用的框架和通用類庫,不管是微軟自己的還是第三方的只要實際項目中好用且可以解決實際問題那都會收集好,編寫好文章和別人一起分享,這樣自己學到了,別人也能學到知識,當今社會很需要知識的搬運工。
Email:[email protected]
本文章地址: http://www.cnblogs.com/wohexiaocai/p/5469253.html
1.基本介紹
由於項目中需要用到各種壓縮將文件進行壓縮下載,減少網絡的帶寬,所以壓縮是一個非常常見的功能,對於壓縮微軟自己也提供了一些類庫
2.實際項目
2.1 壓縮單個文件
寫了兩個方法,可以指定壓縮等級,這樣你的壓縮包大小就不一樣了
2.2 壓縮單個文件夾
public void ZipDir(string dirToZip, string zipedFileName, int compressionLevel = 9)
2.3 壓縮多個文件或者文件夾
public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)
2.4 對壓縮包進行加密
public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)
2.5 直接解壓,無需密碼
public void UnZip(string zipFilePath, string unZipDir)
3.演示圖
3.ZipHelper下載
1 //-------------------------------------------------------------------------------------
2 // All Rights Reserved , Copyright (C) 2016 , ZTO , Ltd .
3 //-------------------------------------------------------------------------------------
4
5 using System;
6 using System.Collections;
7 using System.Collections.Generic;
8 using System.IO;
9
10 namespace ZTO.PicTest.Utilities
11 {
12 using ICSharpCode.SharpZipLib.Checksums;
13 using ICSharpCode.SharpZipLib.Zip;
14
15 /// <summary>
16 /// Zip壓縮幫助類
17 ///
18 /// 修改紀錄
19 ///
20 /// 2015-09-16 版本:1.0 YangHengLian 創建主鍵,注意命名空間的排序。
21 /// 2016-5-7 YangHengLian增加了可以支持多個文件或者多個文件夾打包成一個zip文件
22 ///
23 /// 版本:1.0
24 ///
25 /// <author>
26 /// <name>YangHengLian</name>
27 /// <date>2015-09-16</date>
28 /// </author>
29 /// </summary>
30 public class ZipHelper
31 {
32 /// <summary>
33 /// 壓縮文件夾
34 /// </summary>
35 /// <param name="dirToZip"></param>
36 /// <param name="zipedFileName"></param>
37 /// <param name="compressionLevel">壓縮率0(無壓縮)9(壓縮率最高)</param>
38 public void ZipDir(string dirToZip, string zipedFileName, int compressionLevel = 9)
39 {
40 if (Path.GetExtension(zipedFileName) != ".zip")
41 {
42 zipedFileName = zipedFileName + ".zip";
43 }
44 using (var zipoutputstream = new ZipOutputStream(File.Create(zipedFileName)))
45 {
46 zipoutputstream.SetLevel(compressionLevel);
47 Crc32 crc = new Crc32();
48 Hashtable fileList = GetAllFies(dirToZip);
49 foreach (DictionaryEntry item in fileList)
50 {
51 FileStream fs = new FileStream(item.Key.ToString(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
52 byte[] buffer = new byte[fs.Length];
53 fs.Read(buffer, 0, buffer.Length);
54 // ZipEntry entry = new ZipEntry(item.Key.ToString().Substring(dirToZip.Length + 1));
55 ZipEntry entry = new ZipEntry(Path.GetFileName(item.Key.ToString()))
56 {
57 DateTime = (DateTime) item.Value,
58 Size = fs.Length
59 };
60 fs.Close();
61 crc.Reset();
62 crc.Update(buffer);
63 entry.Crc = crc.Value;
64 zipoutputstream.PutNextEntry(entry);
65 zipoutputstream.Write(buffer, 0, buffer.Length);
66 }
67 }
68 }
69
70 /// <summary>
71 /// 獲取所有文件
72 /// </summary>
73 /// <returns></returns>
74 public Hashtable GetAllFies(string dir)
75 {
76 Hashtable filesList = new Hashtable();
77 DirectoryInfo fileDire = new DirectoryInfo(dir);
78 if (!fileDire.Exists)
79 {
80 throw new FileNotFoundException("目錄:" + fileDire.FullName + "沒有找到!");
81 }
82
83 GetAllDirFiles(fileDire, filesList);
84 GetAllDirsFiles(fileDire.GetDirectories(), filesList);
85 return filesList;
86 }
87
88 /// <summary>
89 /// 獲取一個文件夾下的所有文件夾裡的文件
90 /// </summary>
91 /// <param name="dirs"></param>
92 /// <param name="filesList"></param>
93 public void GetAllDirsFiles(IEnumerable<DirectoryInfo> dirs, Hashtable filesList)
94 {
95 foreach (DirectoryInfo dir in dirs)
96 {
97 foreach (FileInfo file in dir.GetFiles("*.*"))
98 {
99 filesList.Add(file.FullName, file.LastWriteTime);
100 }
101 GetAllDirsFiles(dir.GetDirectories(), filesList);
102 }
103 }
104
105 /// <summary>
106 /// 獲取一個文件夾下的文件
107 /// </summary>
108 /// <param name="dir">目錄名稱</param>
109 /// <param name="filesList">文件列表HastTable</param>
110 public static void GetAllDirFiles(DirectoryInfo dir, Hashtable filesList)
111 {
112 foreach (FileInfo file in dir.GetFiles("*.*"))
113 {
114 filesList.Add(file.FullName, file.LastWriteTime);
115 }
116 }
117
118 /// <summary>
119 /// 功能:解壓zip格式的文件。
120 /// </summary>
121 /// <param name="zipFilePath">壓縮文件路徑</param>
122 /// <param name="unZipDir">解壓文件存放路徑,為空時默認與壓縮文件同一級目錄下,跟壓縮文件同名的文件夾</param>
123 /// <returns>解壓是否成功</returns>
124 public void UnZip(string zipFilePath, string unZipDir)
125 {
126 if (zipFilePath == string.Empty)
127 {
128 throw new Exception("壓縮文件不能為空!");
129 }
130 if (!File.Exists(zipFilePath))
131 {
132 throw new FileNotFoundException("壓縮文件不存在!");
133 }
134 //解壓文件夾為空時默認與壓縮文件同一級目錄下,跟壓縮文件同名的文件夾
135 if (unZipDir == string.Empty)
136 unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
137 if (!unZipDir.EndsWith("/"))
138 unZipDir += "/";
139 if (!Directory.Exists(unZipDir))
140 Directory.CreateDirectory(unZipDir);
141
142 using (var s = new ZipInputStream(File.OpenRead(zipFilePath)))
143 {
144
145 ZipEntry theEntry;
146 while ((theEntry = s.GetNextEntry()) != null)
147 {
148 string directoryName = Path.GetDirectoryName(theEntry.Name);
149 string fileName = Path.GetFileName(theEntry.Name);
150 if (!string.IsNullOrEmpty(directoryName))
151 {
152 Directory.CreateDirectory(unZipDir + directoryName);
153 }
154 if (directoryName != null && !directoryName.EndsWith("/"))
155 {
156 }
157 if (fileName != String.Empty)
158 {
159 using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
160 {
161
162 int size;
163 byte[] data = new byte[2048];
164 while (true)
165 {
166 size = s.Read(data, 0, data.Length);
167 if (size > 0)
168 {
169 streamWriter.Write(data, 0, size);
170 }
171 else
172 {
173 break;
174 }
175 }
176 }
177 }
178 }
179 }
180 }
181
182 /// <summary>
183 /// 壓縮單個文件
184 /// </summary>
185 /// <param name="filePath">被壓縮的文件名稱(包含文件路徑),文件的全路徑</param>
186 /// <param name="zipedFileName">壓縮後的文件名稱(包含文件路徑),保存的文件名稱</param>
187 /// <param name="compressionLevel">壓縮率0(無壓縮)到 9(壓縮率最高)</param>
188 public void ZipFile(string filePath, string zipedFileName, int compressionLevel = 9)
189 {
190 // 如果文件沒有找到,則報錯
191 if (!File.Exists(filePath))
192 {
193 throw new FileNotFoundException("文件:" + filePath + "沒有找到!");
194 }
195 // 如果壓縮後名字為空就默認使用源文件名稱作為壓縮文件名稱
196 if (string.IsNullOrEmpty(zipedFileName))
197 {
198 string oldValue = Path.GetFileName(filePath);
199 if (oldValue != null)
200 {
201 zipedFileName = filePath.Replace(oldValue, "") + Path.GetFileNameWithoutExtension(filePath) + ".zip";
202 }
203 }
204 // 如果壓縮後的文件名稱後綴名不是zip,就是加上zip,防止是一個亂碼文件
205 if (Path.GetExtension(zipedFileName) != ".zip")
206 {
207 zipedFileName = zipedFileName + ".zip";
208 }
209 // 如果指定位置目錄不存在,創建該目錄 C:\Users\yhl\Desktop\大漢三通
210 string zipedDir = zipedFileName.Substring(0, zipedFileName.LastIndexOf("\\", StringComparison.Ordinal));
211 if (!Directory.Exists(zipedDir))
212 {
213 Directory.CreateDirectory(zipedDir);
214 }
215 // 被壓縮文件名稱
216 string filename = filePath.Substring(filePath.LastIndexOf("\\", StringComparison.Ordinal) + 1);
217 var streamToZip = new FileStream(filePath, FileMode.Open, FileAccess.Read);
218 var zipFile = File.Create(zipedFileName);
219 var zipStream = new ZipOutputStream(zipFile);
220 var zipEntry = new ZipEntry(filename);
221 zipStream.PutNextEntry(zipEntry);
222 zipStream.SetLevel(compressionLevel);
223 var buffer = new byte[2048];
224 Int32 size = streamToZip.Read(buffer, 0, buffer.Length);
225 zipStream.Write(buffer, 0, size);
226 try
227 {
228 while (size < streamToZip.Length)
229 {
230 int sizeRead = streamToZip.Read(buffer, 0, buffer.Length);
231 zipStream.Write(buffer, 0, sizeRead);
232 size += sizeRead;
233 }
234 }
235 finally
236 {
237 zipStream.Finish();
238 zipStream.Close();
239 streamToZip.Close();
240 }
241 }
242
243 /// <summary>
244 /// 壓縮單個文件
245 /// </summary>
246 /// <param name="fileToZip">要進行壓縮的文件名,全路徑</param>
247 /// <param name="zipedFile">壓縮後生成的壓縮文件名,全路徑</param>
248 public void ZipFile(string fileToZip, string zipedFile)
249 {
250 // 如果文件沒有找到,則報錯
251 if (!File.Exists(fileToZip))
252 {
253 throw new FileNotFoundException("指定要壓縮的文件: " + fileToZip + " 不存在!");
254 }
255 using (FileStream fileStream = File.OpenRead(fileToZip))
256 {
257 byte[] buffer = new byte[fileStream.Length];
258 fileStream.Read(buffer, 0, buffer.Length);
259 fileStream.Close();
260 using (FileStream zipFile = File.Create(zipedFile))
261 {
262 using (ZipOutputStream zipOutputStream = new ZipOutputStream(zipFile))
263 {
264 // string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1);
265 string fileName = Path.GetFileName(fileToZip);
266 var zipEntry = new ZipEntry(fileName)
267 {
268 DateTime = DateTime.Now,
269 IsUnicodeText = true
270 };
271 zipOutputStream.PutNextEntry(zipEntry);
272 zipOutputStream.SetLevel(5);
273 zipOutputStream.Write(buffer, 0, buffer.Length);
274 zipOutputStream.Finish();
275 zipOutputStream.Close();
276 }
277 }
278 }
279 }
280
281 /// <summary>
282 /// 壓縮多個目錄或文件
283 /// </summary>
284 /// <param name="folderOrFileList">待壓縮的文件夾或者文件,全路徑格式,是一個集合</param>
285 /// <param name="zipedFile">壓縮後的文件名,全路徑格式</param>
286 /// <param name="password">壓宿密碼</param>
287 /// <returns></returns>
288 public bool ZipManyFilesOrDictorys(IEnumerable<string> folderOrFileList, string zipedFile, string password)
289 {
290 bool res = true;
291 using (var s = new ZipOutputStream(File.Create(zipedFile)))
292 {
293 s.SetLevel(6);
294 if (!string.IsNullOrEmpty(password))
295 {
296 s.Password = password;
297 }
298 foreach (string fileOrDir in folderOrFileList)
299 {
300 //是文件夾
301 if (Directory.Exists(fileOrDir))
302 {
303 res = ZipFileDictory(fileOrDir, s, "");
304 }
305 else
306 {
307 //文件
308 res = ZipFileWithStream(fileOrDir, s);
309 }
310 }
311 s.Finish();
312 s.Close();
313 return res;
314 }
315 }
316
317 /// <summary>
318 /// 帶壓縮流壓縮單個文件
319 /// </summary>
320 /// <param name="fileToZip">要進行壓縮的文件名</param>
321 /// <param name="zipStream"></param>
322 /// <returns></returns>
323 private bool ZipFileWithStream(string fileToZip, ZipOutputStream zipStream)
324 {
325 //如果文件沒有找到,則報錯
326 if (!File.Exists(fileToZip))
327 {
328 throw new FileNotFoundException("指定要壓縮的文件: " + fileToZip + " 不存在!");
329 }
330 //FileStream fs = null;
331 FileStream zipFile = null;
332 ZipEntry zipEntry = null;
333 bool res = true;
334 try
335 {
336 zipFile = File.OpenRead(fileToZip);
337 byte[] buffer = new byte[zipFile.Length];
338 zipFile.Read(buffer, 0, buffer.Length);
339 zipFile.Close();
340 zipEntry = new ZipEntry(Path.GetFileName(fileToZip));
341 zipStream.PutNextEntry(zipEntry);
342 zipStream.Write(buffer, 0, buffer.Length);
343 }
344 catch
345 {
346 res = false;
347 }
348 finally
349 {
350 if (zipEntry != null)
351 {
352 }
353
354 if (zipFile != null)
355 {
356 zipFile.Close();
357 }
358 GC.Collect();
359 GC.Collect(1);
360 }
361 return res;
362
363 }
364
365 /// <summary>
366 /// 遞歸壓縮文件夾方法
367 /// </summary>
368 /// <param name="folderToZip"></param>
369 /// <param name="s"></param>
370 /// <param name="parentFolderName"></param>
371 private bool ZipFileDictory(string folderToZip, ZipOutputStream s, string parentFolderName)
372 {
373 bool res = true;
374 ZipEntry entry = null;
375 FileStream fs = null;
376 Crc32 crc = new Crc32();
377 try
378 {
379 //創建當前文件夾
380 entry = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/")); //加上 “/” 才會當成是文件夾創建
381 s.PutNextEntry(entry);
382 s.Flush();
383 //先壓縮文件,再遞歸壓縮文件夾
384 var filenames = Directory.GetFiles(folderToZip);
385 foreach (string file in filenames)
386 {
387 //打開壓縮文件
388 fs = File.OpenRead(file);
389 byte[] buffer = new byte[fs.Length];
390 fs.Read(buffer, 0, buffer.Length);
391 entry = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));
392 entry.DateTime = DateTime.Now;
393 entry.Size = fs.Length;
394 fs.Close();
395 crc.Reset();
396 crc.Update(buffer);
397 entry.Crc = crc.Value;
398 s.PutNextEntry(entry);
399 s.Write(buffer, 0, buffer.Length);
400 }
401 }
402 catch
403 {
404 res = false;
405 }
406 finally
407 {
408 if (fs != null)
409 {
410 fs.Close();
411 }
412 if (entry != null)
413 {
414 }
415 GC.Collect();
416 GC.Collect(1);
417 }
418 var folders = Directory.GetDirectories(folderToZip);
419 foreach (string folder in folders)
420 {
421 if (!ZipFileDictory(folder, s, Path.Combine(parentFolderName, Path.GetFileName(folderToZip))))
422 {
423 return false;
424 }
425 }
426 return res;
427 }
428 }
429 }
View Code
慢慢積累,你的這些代碼都是你的財富,可以幫你提高工作效率,勤勤懇懇的干好每件事情,點滴積累,開心編程。