C#实现Zip压缩解压实例
原文地址:https://www.cnblogs.com/GoCircle/p/6544678.html
本文只列举一个压缩帮助类,使用的是有要添加一个dll引用ICSharpCode.SharpZipLib.dll【下载地址】。
这个类压缩格式是ZIP的,文件后缀写成 .zip。如果用这个类来解压rar格式的压缩文件时会报错。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.IO; 6 using ICSharpCode.SharpZipLib; 7 using ICSharpCode.SharpZipLib.Zip; 8 using ICSharpCode.SharpZipLib.Checksums; 9 10 namespace CLeopardZip 11 { 12 /// <summary> 13 /// 适用与ZIP压缩 14 /// </summary> 15 public class ZipHelper 16 { 17 #region 压缩 18 19 /// <summary> 20 /// 递归压缩文件夹的内部方法 21 /// </summary> 22 /// <param name="folderToZip">要压缩的文件夹路径</param> 23 /// <param name="zipStream">压缩输出流</param> 24 /// <param name="parentFolderName">此文件夹的上级文件夹</param> 25 /// <returns></returns> 26 private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName) 27 { 28 bool result = true; 29 string[] folders, files; 30 ZipEntry ent = null; 31 FileStream fs = null; 32 Crc32 crc = new Crc32(); 33 34 try 35 { 36 ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/")); 37 zipStream.PutNextEntry(ent); 38 zipStream.Flush(); 39 40 files = Directory.GetFiles(folderToZip); 41 foreach (string file in files) 42 { 43 fs = File.OpenRead(file); 44 45 byte[] buffer = new byte[fs.Length]; 46 fs.Read(buffer, 0, buffer.Length); 47 ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file))); 48 ent.DateTime = DateTime.Now; 49 ent.Size = fs.Length; 50 51 fs.Close(); 52 53 crc.Reset(); 54 crc.Update(buffer); 55 56 ent.Crc = crc.Value; 57 zipStream.PutNextEntry(ent); 58 zipStream.Write(buffer, 0, buffer.Length); 59 } 60 61 } 62 catch 63 { 64 result = false; 65 } 66 finally 67 { 68 if (fs != null) 69 { 70 fs.Close(); 71 fs.Dispose(); 72 } 73 if (ent != null) 74 { 75 ent = null; 76 } 77 GC.Collect(); 78 GC.Collect(1); 79 } 80 81 folders = Directory.GetDirectories(folderToZip); 82 foreach (string folder in folders) 83 if (!ZipDirectory(folder, zipStream, folderToZip)) 84 return false; 85 86 return result; 87 } 88 89 /// <summary> 90 /// 压缩文件夹 91 /// </summary> 92 /// <param name="folderToZip">要压缩的文件夹路径</param> 93 /// <param name="zipedFile">压缩文件完整路径</param> 94 /// <param name="password">密码</param> 95 /// <returns>是否压缩成功</returns> 96 public static bool ZipDirectory(string folderToZip, string zipedFile, string password) 97 { 98 bool result = false; 99 if (!Directory.Exists(folderToZip)) 100 return result; 101 102 ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile)); 103 zipStream.SetLevel(6); 104 if (!string.IsNullOrEmpty(password)) zipStream.Password = password; 105 106 result = ZipDirectory(folderToZip, zipStream, ""); 107 108 zipStream.Finish(); 109 zipStream.Close(); 110 111 return result; 112 } 113 114 /// <summary> 115 /// 压缩文件夹 116 /// </summary> 117 /// <param name="folderToZip">要压缩的文件夹路径</param> 118 /// <param name="zipedFile">压缩文件完整路径</param> 119 /// <returns>是否压缩成功</returns> 120 public static bool ZipDirectory(string folderToZip, string zipedFile) 121 { 122 bool result = ZipDirectory(folderToZip, zipedFile, null); 123 return result; 124 } 125 126 /// <summary> 127 /// 压缩文件 128 /// </summary> 129 /// <param name="fileToZip">要压缩的文件全名</param> 130 /// <param name="zipedFile">压缩后的文件名</param> 131 /// <param name="password">密码</param> 132 /// <returns>压缩结果</returns> 133 public static bool ZipFile(string fileToZip, string zipedFile, string password) 134 { 135 bool result = true; 136 ZipOutputStream zipStream = null; 137 FileStream fs = null; 138 ZipEntry ent = null; 139 140 if (!File.Exists(fileToZip)) 141 return false; 142 143 try 144 { 145 fs = File.OpenRead(fileToZip); 146 byte[] buffer = new byte[fs.Length]; 147 fs.Read(buffer, 0, buffer.Length); 148 fs.Close(); 149 150 fs = File.Create(zipedFile); 151 zipStream = new ZipOutputStream(fs); 152 if (!string.IsNullOrEmpty(password)) zipStream.Password = password; 153 ent = new ZipEntry(Path.GetFileName(fileToZip)); 154 zipStream.PutNextEntry(ent); 155 zipStream.SetLevel(6); 156 157 zipStream.Write(buffer, 0, buffer.Length); 158 159 } 160 catch 161 { 162 result = false; 163 } 164 finally 165 { 166 if (zipStream != null) 167 { 168 zipStream.Finish(); 169 zipStream.Close(); 170 } 171 if (ent != null) 172 { 173 ent = null; 174 } 175 if (fs != null) 176 { 177 fs.Close(); 178 fs.Dispose(); 179 } 180 } 181 GC.Collect(); 182 GC.Collect(1); 183 184 return result; 185 } 186 187 /// <summary> 188 /// 压缩文件 189 /// </summary> 190 /// <param name="fileToZip">要压缩的文件全名</param> 191 /// <param name="zipedFile">压缩后的文件名</param> 192 /// <returns>压缩结果</returns> 193 public static bool ZipFile(string fileToZip, string zipedFile) 194 { 195 bool result = ZipFile(fileToZip, zipedFile, null); 196 return result; 197 } 198 199 /// <summary> 200 /// 压缩文件或文件夹 201 /// </summary> 202 /// <param name="fileToZip">要压缩的路径</param> 203 /// <param name="zipedFile">压缩后的文件名</param> 204 /// <param name="password">密码</param> 205 /// <returns>压缩结果</returns> 206 public static bool Zip(string fileToZip, string zipedFile, string password) 207 { 208 bool result = false; 209 if (Directory.Exists(fileToZip)) 210 result = ZipDirectory(fileToZip, zipedFile, password); 211 else if (File.Exists(fileToZip)) 212 result = ZipFile(fileToZip, zipedFile, password); 213 214 return result; 215 } 216 217 /// <summary> 218 /// 压缩文件或文件夹 219 /// </summary> 220 /// <param name="fileToZip">要压缩的路径</param> 221 /// <param name="zipedFile">压缩后的文件名</param> 222 /// <returns>压缩结果</returns> 223 public static bool Zip(string fileToZip, string zipedFile) 224 { 225 bool result = Zip(fileToZip, zipedFile, null); 226 return result; 227 228 } 229 230 #endregion 231 232 #region 解压 233 234 /// <summary> 235 /// 解压功能(解压压缩文件到指定目录) 236 /// </summary> 237 /// <param name="fileToUnZip">待解压的文件</param> 238 /// <param name="zipedFolder">指定解压目标目录</param> 239 /// <param name="password">密码</param> 240 /// <returns>解压结果</returns> 241 public static bool UnZip(string fileToUnZip, string zipedFolder, string password) 242 { 243 bool result = true; 244 FileStream fs = null; 245 ZipInputStream zipStream = null; 246 ZipEntry ent = null; 247 string fileName; 248 249 if (!File.Exists(fileToUnZip)) 250 return false; 251 252 if (!Directory.Exists(zipedFolder)) 253 Directory.CreateDirectory(zipedFolder); 254 255 try 256 { 257 zipStream = new ZipInputStream(File.OpenRead(fileToUnZip)); 258 if (!string.IsNullOrEmpty(password)) zipStream.Password = password; 259 while ((ent = zipStream.GetNextEntry()) != null) 260 { 261 if (!string.IsNullOrEmpty(ent.Name)) 262 { 263 fileName = Path.Combine(zipedFolder, ent.Name); 264 fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi 265 266 int index = ent.Name.LastIndexOf('/'); 267 if (index != -1 || fileName.EndsWith("\\")) 268 { 269 string tmpDir = (index != -1 ? fileName.Substring(0, fileName.LastIndexOf('\\')) : fileName) + "\\"; 270 if (!Directory.Exists(tmpDir)) 271 { 272 Directory.CreateDirectory(tmpDir); 273 } 274 if (tmpDir == fileName) 275 { 276 continue; 277 } 278 } 279 280 fs = File.Create(fileName); 281 int size = 2048; 282 byte[] data = new byte[size]; 283 while (true) 284 { 285 size = zipStream.Read(data, 0, data.Length); 286 if (size > 0) 287 fs.Write(data, 0, data.Length); 288 else 289 break; 290 } 291 } 292 } 293 } 294 catch 295 { 296 result = false; 297 } 298 finally 299 { 300 if (fs != null) 301 { 302 fs.Close(); 303 fs.Dispose(); 304 } 305 if (zipStream != null) 306 { 307 zipStream.Close(); 308 zipStream.Dispose(); 309 } 310 if (ent != null) 311 { 312 ent = null; 313 } 314 GC.Collect(); 315 GC.Collect(1); 316 } 317 return result; 318 } 319 320 /// <summary> 321 /// 解压功能(解压压缩文件到指定目录) 322 /// </summary> 323 /// <param name="fileToUnZip">待解压的文件</param> 324 /// <param name="zipedFolder">指定解压目标目录</param> 325 /// <returns>解压结果</returns> 326 public static bool UnZip(string fileToUnZip, string zipedFolder) 327 { 328 bool result = UnZip(fileToUnZip, zipedFolder, null); 329 return result; 330 } 331 332 #endregion 333 } 334 }
这个不同于之前用的zip压缩类,压缩后文件不会乱码。
补充:UnZip方法修复,解决压缩包内包含文件夹,可能没有优先创建文件夹,从而报错【未能找到路径“”的一部分。】