本文通过一个简单的小例子简述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, 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 }
备注
关于生成压缩的方法还有很多,如通过命令行调用winrar的执行文件,SharpZipLib只是方法之一。
关于SharpZipLib的的API文档,可参看链接。
关于源码下载链接