在Visual Studio中可以通過NuGet程序包管理控制台輸入命令PM> Install-Package SharpZipLib或者用NuGet管理界面搜索並安裝。
我把使用SharpZipLib的方法卸載一個類裡面,作為靜態方法調用,免去創建類的麻煩。其中核心壓縮和解壓文件的方法代碼如下:
1 /// <summary>
2 /// 壓縮多個文件/文件夾
3 /// </summary>
4 /// <param name="sourceList">源文件/文件夾路徑列表</param>
5 /// <param name="zipFilePath">壓縮文件路徑</param>
6 /// <param name="comment">注釋信息</param>
7 /// <param name="password">壓縮密碼</param>
8 /// <param name="compressionLevel">壓縮等級,范圍從0到9,可選,默認為6</param>
9 /// <returns></returns>
10 public static bool CompressFile(IEnumerable<string> sourceList, string zipFilePath,
11 string comment = null, string password = null, int compressionLevel = 6)
12 {
13 bool result = false;
14
15 try
16 {
17 //檢測目標文件所屬的文件夾是否存在,如果不存在則建立
18 string zipFileDirectory = Path.GetDirectoryName(zipFilePath);
19 if (!Directory.Exists(zipFileDirectory))
20 {
21 Directory.CreateDirectory(zipFileDirectory);
22 }
23
24 Dictionary<string, string> dictionaryList = PrepareFileSystementities(sourceList);
25
26 using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipFilePath)))
27 {
28 zipStream.Password = password;//設置密碼
29 zipStream.SetComment(comment);//添加注釋
30 zipStream.SetLevel(CheckCompressionLevel(compressionLevel));//設置壓縮等級
31
32 foreach (string key in dictionaryList.Keys)//從字典取文件添加到壓縮文件
33 {
34 if (File.Exists(key))//判斷是文件還是文件夾
35 {
36 FileInfo fileItem = new FileInfo(key);
37
38 using (FileStream readStream = fileItem.Open(FileMode.Open,
39 FileAccess.Read, FileShare.Read))
40 {
41 ZipEntry zipEntry = new ZipEntry(dictionaryList[key]);
42 zipEntry.DateTime = fileItem.LastWriteTime;
43 zipEntry.Size = readStream.Length;
44 zipStream.PutNextEntry(zipEntry);
45 int readLength = 0;
46 byte[] buffer = new byte[BufferSize];
47
48 do
49 {
50 readLength = readStream.Read(buffer, 0, BufferSize);
51 zipStream.Write(buffer, 0, readLength);
52 } while (readLength == BufferSize);
53
54 readStream.Close();
55 }
56 }
57 else//對文件夾的處理
58 {
59 ZipEntry zipEntry = new ZipEntry(dictionaryList[key] + "/");
60 zipStream.PutNextEntry(zipEntry);
61 }
62 }
63
64 zipStream.Flush();
65 zipStream.Finish();
66 zipStream.Close();
67 }
68
69 result = true;
70 }
71 catch (System.Exception ex)
72 {
73 throw new Exception("壓縮文件失敗", ex);
74 }
75
76 return result;
77 }
78
79 /// <summary>
80 /// 解壓文件到指定文件夾
81 /// </summary>
82 /// <param name="sourceFile">壓縮文件</param>
83 /// <param name="destinationDirectory">目標文件夾,如果為空則解壓到當前文件夾下</param>
84 /// <param name="password">密碼</param>
85 /// <returns></returns>
86 public static bool DecomparessFile(string sourceFile, string destinationDirectory = null, string password = null)
87 {
88 bool result = false;
89
90 if (!File.Exists(sourceFile))
91 {
92 throw new FileNotFoundException("要解壓的文件不存在", sourceFile);
93 }
94
95 if (string.IsNullOrWhiteSpace(destinationDirectory))
96 {
97 destinationDirectory = Path.GetDirectoryName(sourceFile);
98 }
99
100 try
101 {
102 if (!Directory.Exists(destinationDirectory))
103 {
104 Directory.CreateDirectory(destinationDirectory);
105 }
106
107 using (ZipInputStream zipStream = new ZipInputStream(File.Open(sourceFile, FileMode.Open,
108 FileAccess.Read, FileShare.Read)))
109 {
110 zipStream.Password = password;
111 ZipEntry zipEntry = zipStream.GetNextEntry();
112
113 while (zipEntry != null)
114 {
115 if (zipEntry.IsDirectory)//如果是文件夾則創建
116 {
117 Directory.CreateDirectory(Path.Combine(destinationDirectory,
118 Path.GetDirectoryName(zipEntry.Name)));
119 }
120 else
121 {
122 string fileName = Path.GetFileName(zipEntry.Name);
123 if (!string.IsNullOrEmpty(fileName) && fileName.Trim().Length > 0)
124 {
125 FileInfo fileItem = new FileInfo(Path.Combine(destinationDirectory, zipEntry.Name));
126 using (FileStream writeStream = fileItem.Create())
127 {
128 byte[] buffer = new byte[BufferSize];
129 int readLength = 0;
130
131 do
132 {
133 readLength = zipStream.Read(buffer, 0, BufferSize);
134 writeStream.Write(buffer, 0, readLength);
135 } while (readLength == BufferSize);
136
137 writeStream.Flush();
138 writeStream.Close();
139 }
140 fileItem.LastWriteTime = zipEntry.DateTime;
141 }
142 }
143 zipEntry = zipStream.GetNextEntry();//獲取下一個文件
144 }
145
146 zipStream.Close();
147 }
148 result = true;
149 }
150 catch (System.Exception ex)
151 {
152 throw new Exception("文件解壓發生錯誤", ex);
153 }
154
155 return result;
156 }
壓縮方法CompressFile中sourceList是路徑數組,支持文件夾和文件的路徑。當遇到文件夾時會自動將下級文件和文件夾包含,並會檢測重復項。文件路徑處理的方法如下:
1 /// <summary>
2 /// 為壓縮准備文件系統對象
3 /// </summary>
4 /// <param name="sourceFileEntityPathList"></param>
5 /// <returns></returns>
6 private static Dictionary<string, string> PrepareFileSystementities(IEnumerable<string> sourceFileEntityPathList)
7 {
8 Dictionary<string, string> fileEntityDictionary = new Dictionary<string, string>();//文件字典
9 string parentDirectoryPath = "";
10 foreach (string fileEntityPath in sourceFileEntityPathList)
11 {
12 string path = fileEntityPath;
13 //保證傳入的文件夾也被壓縮進文件
14 if (path.EndsWith(@"\"))
15 {
16 path = path.Remove(path.LastIndexOf(@"\"));
17 }
18
19 parentDirectoryPath = Path.GetDirectoryName(path) + @"\";
20
21 if (parentDirectoryPath.EndsWith(@":\\"))//防止根目錄下把盤符壓入的錯誤
22 {
23 parentDirectoryPath = parentDirectoryPath.Replace(@"\\", @"\");
24 }
25
26 //獲取目錄中所有的文件系統對象
27 Dictionary<string, string> subDictionary = GetAllFileSystemEntities(path, parentDirectoryPath);
28
29 //將文件系統對象添加到總的文件字典中
30 foreach (string key in subDictionary.Keys)
31 {
32 if (!fileEntityDictionary.ContainsKey(key))//檢測重復項
33 {
34 fileEntityDictionary.Add(key, subDictionary[key]);
35 }
36 }
37 }
38 return fileEntityDictionary;
39 }
40
41 /// <summary>
42 /// 獲取所有文件系統對象
43 /// </summary>
44 /// <param name="source">源路徑</param>
45 /// <param name="topDirectory">頂級文件夾</param>
46 /// <returns>字典中Key為完整路徑,Value為文件(夾)名稱</returns>
47 private static Dictionary<string, string> GetAllFileSystemEntities(string source, string topDirectory)
48 {
49 Dictionary<string, string> entitiesDictionary = new Dictionary<string, string>();
50 entitiesDictionary.Add(source, source.Replace(topDirectory, ""));
51
52 if (Directory.Exists(source))
53 {
54 //一次性獲取下級所有目錄,避免遞歸
55 string[] directories = Directory.GetDirectories(source, "*.*", SearchOption.AllDirectories);
56 foreach (string directory in directories)
57 {
58 entitiesDictionary.Add(directory, directory.Replace(topDirectory, ""));
59 }
60
61 string[] files = Directory.GetFiles(source, "*.*", SearchOption.AllDirectories);
62 foreach (string file in files)
63 {
64 entitiesDictionary.Add(file, file.Replace(topDirectory, ""));
65 }
66 }
67
68 return entitiesDictionary;
69 }
除了支持文件和文件夾壓縮解壓,還提供了對字節的壓縮解壓方法:

為了測試該類,我寫了一個WinForm程序,界面如下:
可以將文件和文件夾拖放到壓縮列表中,選中壓縮列表中的對象可以按Delete鍵進行刪除。文件解壓區域也可以將要解壓的文件拖放到文件路徑輸入文本框。實際測試可以正確壓縮和解壓,包括設置密碼,壓縮和解壓操作和WinRAR完全兼容。如果您在代碼中發現問題或有可以優化完善的地方,歡迎指出,謝謝!
程序源代碼下載:http://files.cnblogs.com/files/conexpress/SharpZipTest.zip
參考資料:
http://www.cnblogs.com/kissdodog/p/3525295.html
http://www.cnblogs.com/xuanye/archive/2011/10/19/2217211.html