c#操作壓縮檔案(ICSharpCode)
阿新 • • 發佈:2018-12-14
網上轉過來的,經測試很好用。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using ICSharpCode.SharpZipLib; using ICSharpCode.SharpZipLib.Zip; using ICSharpCode.SharpZipLib.Checksums; namespace UnZip { public static class DealZip { #region 壓縮 #region 公開壓縮方法 /// <summary> /// 壓縮檔案或資料夾 ----帶密碼 /// </summary> /// <param name="fileToZip">要壓縮的路徑-資料夾或者檔案</param> /// <param name="zipedFile">壓縮後的檔名</param> /// <param name="password">密碼</param> /// <param name="errorOut">如果失敗返回失敗資訊</param> /// <returns>壓縮結果</returns> public static bool Zip(string fileToZip, string zipedFile, string password, ref string errorOut) { bool result = false; try { if (Directory.Exists(fileToZip)) result = ZipDirectory(fileToZip, zipedFile, password); else if (File.Exists(fileToZip)) result = ZipFile(fileToZip, zipedFile, password); } catch (Exception ex) { errorOut = ex.Message; } return result; } /// <summary> /// 壓縮檔案或資料夾 ----無密碼 /// </summary> /// <param name="fileToZip">要壓縮的路徑-資料夾或者檔案</param> /// <param name="zipedFile">壓縮後的檔名</param> /// <param name="errorOut">如果失敗返回失敗資訊</param> /// <returns>壓縮結果</returns> public static bool Zip(string fileToZip, string zipedFile, ref string errorOut) { bool result = false; try { if (Directory.Exists(fileToZip)) result = ZipDirectory(fileToZip, zipedFile, null); else if (File.Exists(fileToZip)) result = ZipFile(fileToZip, zipedFile, null); } catch (Exception ex) { errorOut = ex.Message; } return result; } #endregion #region 內部處理方法 /// <summary> /// 壓縮檔案 /// </summary> /// <param name="fileToZip">要壓縮的檔案全名</param> /// <param name="zipedFile">壓縮後的檔名</param> /// <param name="password">密碼</param> /// <returns>壓縮結果</returns> private static bool ZipFile(string fileToZip, string zipedFile, string password) { bool result = true; ZipOutputStream zipStream = null; FileStream fs = null; ZipEntry ent = null; if (!File.Exists(fileToZip)) return false; try { fs = File.OpenRead(fileToZip); byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); fs.Close(); fs = File.Create(zipedFile); zipStream = new ZipOutputStream(fs); if (!string.IsNullOrEmpty(password)) zipStream.Password = password; ent = new ZipEntry(Path.GetFileName(fileToZip)); zipStream.PutNextEntry(ent); zipStream.SetLevel(6); zipStream.Write(buffer, 0, buffer.Length); } catch (Exception ex) { result = false; throw ex; } finally { if (zipStream != null) { zipStream.Finish(); zipStream.Close(); } if (ent != null) { ent = null; } if (fs != null) { fs.Close(); fs.Dispose(); } } GC.Collect(); GC.Collect(1); return result; } /// <summary> /// 壓縮資料夾 /// </summary> /// <param name="strFile">帶壓縮的資料夾目錄</param> /// <param name="strZip">壓縮後的檔名</param> /// <param name="password">壓縮密碼</param> /// <returns>是否壓縮成功</returns> private static bool ZipDirectory(string strFile, string strZip, string password) { bool result = false; if (!Directory.Exists(strFile)) return false; if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar) strFile += Path.DirectorySeparatorChar; ZipOutputStream s = new ZipOutputStream(File.Create(strZip)); s.SetLevel(6); // 0 - store only to 9 - means best compression if (!string.IsNullOrEmpty(password)) s.Password = password; try { result = zip(strFile, s, strFile); } catch (Exception ex) { throw ex; } finally { s.Finish(); s.Close(); } return result; } /// <summary> /// 壓縮資料夾內部方法 /// </summary> /// <param name="strFile"></param> /// <param name="s"></param> /// <param name="staticFile"></param> /// <returns></returns> private static bool zip(string strFile, ZipOutputStream s, string staticFile) { bool result = true; if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar) strFile += Path.DirectorySeparatorChar; Crc32 crc = new Crc32(); try { string[] filenames = Directory.GetFileSystemEntries(strFile); foreach (string file in filenames) { if (Directory.Exists(file)) { zip(file, s, staticFile); } else // 否則直接壓縮檔案 { //開啟壓縮檔案 FileStream fs = File.OpenRead(file); byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); string tempfile = file.Substring(staticFile.LastIndexOf("\\") + 1); ZipEntry entry = new ZipEntry(tempfile); entry.DateTime = DateTime.Now; entry.Size = fs.Length; fs.Close(); crc.Reset(); crc.Update(buffer); entry.Crc = crc.Value; s.PutNextEntry(entry); s.Write(buffer, 0, buffer.Length); } } } catch (Exception ex) { result = false; throw ex; } return result; } #endregion #endregion #region 解壓 #region 公開解壓方法 /// <summary> /// 解壓功能(解壓壓縮檔案到指定目錄)---->不需要密碼 /// </summary> /// <param name="fileToUnZip">待解壓的檔案</param> /// <param name="zipedFolder">指定解壓目標目錄</param> /// <param name="errorOut">如果失敗返回失敗資訊</param> /// <returns>解壓結果</returns> public static bool UPZipFile(string fileToUnZip, string zipedFolder, ref string errorOut) { bool result = false; try { result = UPZipFileByPassword(fileToUnZip, zipedFolder, null); } catch (Exception ex) { errorOut = ex.Message; } return result; } /// <summary> /// 解壓功能(解壓壓縮檔案到指定目錄)---->需要密碼 /// </summary> /// <param name="fileToUnZip">待解壓的檔案</param> /// <param name="zipedFolder">指定解壓目標目錄</param> /// <param name="password">密碼</param> /// <param name="errorOut">如果失敗返回失敗資訊</param> /// <returns>解壓結果</returns> public static bool UPZipFile(string fileToUnZip, string zipedFolder, string password, ref string errorOut) { bool result = false; try { result = UPZipFileByPassword(fileToUnZip, zipedFolder, password); } catch (Exception ex) { errorOut = ex.Message; } return result; } #endregion #region 內部處理方法 /// <summary> /// 解壓功能 內部處理方法 /// </summary> /// <param name="TargetFile">待解壓的檔案</param> /// <param name="fileDir">指定解壓目標目錄</param> /// <param name="password">密碼</param> /// <returns>成功返回true</returns> private static bool UPZipFileByPassword(string TargetFile, string fileDir, string password) { bool rootFile = true; try { //讀取壓縮檔案(zip檔案),準備解壓縮 ZipInputStream zipStream = new ZipInputStream(File.OpenRead(TargetFile.Trim())); ZipEntry theEntry; string path = fileDir; string rootDir = " "; if (!string.IsNullOrEmpty(password)) zipStream.Password = password; while ((theEntry = zipStream.GetNextEntry()) != null) { rootDir = Path.GetDirectoryName(theEntry.Name); if (rootDir.IndexOf("\\") >= 0) { rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1); } string dir = Path.GetDirectoryName(theEntry.Name); string fileName = Path.GetFileName(theEntry.Name); if (dir != " ") { if (!Directory.Exists(fileDir + "\\" + dir)) { path = fileDir + "\\" + dir; Directory.CreateDirectory(path); } } else if (dir == " " && fileName != "") { path = fileDir; } else if (dir != " " && fileName != "") { if (dir.IndexOf("\\") > 0) { path = fileDir + "\\" + dir; } } if (dir == rootDir) { path = fileDir + "\\" + rootDir; } //以下為解壓縮zip檔案的基本步驟 //基本思路就是遍歷壓縮檔案裡的所有檔案,建立一個相同的檔案。 if (fileName != String.Empty) { FileStream streamWriter = File.Create(path + "\\" + fileName); int size = 2048; byte[] data = new byte[2048]; while (true) { size = zipStream.Read(data, 0, data.Length); if (size > 0) { streamWriter.Write(data, 0, size); } else { break; } } streamWriter.Close(); } } if (theEntry != null) { theEntry = null; } if (zipStream != null) { zipStream.Close(); } } catch (Exception ex) { rootFile = false; throw ex; } finally { GC.Collect(); GC.Collect(1); } return rootFile; } #endregion #endregion } }