壓縮庫SharpZipLib的應用

来源:http://www.cnblogs.com/conexpress/archive/2016/08/25/SharpZipClass.html
-Advertisement-
Play Games

本文介紹壓縮庫SharpZipLib的使用,提供封裝類的源代碼,以及測試UI的源代碼。 ...


   SharpZipLib是一個開源的C#壓縮解壓庫,應用非常廣泛。就像用ADO.NET操作資料庫要打開連接、執行命令、關閉連接等多個步驟一樣,用SharpZipLib進行壓縮和解壓也需要多個步驟。除了初學者會用原始的方法做一步一步完成,實際開發的時候都會進行更易用的封裝。這裡分享我對SharpZipLib的封裝,支持對文件和位元組進行壓縮和解壓操作,支持多個文件和文件夾壓縮,支持設置備註和密碼。(文章源網址:http://www.cnblogs.com/conexpress/p/SharpZipClass.html)     SharpZipLib的官方地址是:http://icsharpcode.github.io/SharpZipLib/,實際使用可以通過NuGet獲取,在NuGetd地址是:http://www.nuget.org/packages/SharpZipLib/ SharpZipLib_NuGet   在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         }

除了支持文件和文件夾壓縮解壓,還提供了對位元組的壓縮解壓方法:

  1         /// <summary>
  2         /// 壓縮位元組數組
  3         /// </summary>
  4         /// <param name="sourceBytes">源位元組數組</param>
  5         /// <param name="compressionLevel">壓縮等級</param>
  6         /// <param name="password">密碼</param>
  7         /// <returns>壓縮後的位元組數組</returns>
  8         public static byte[] CompressBytes(byte[] sourceBytes, string password = null, int compressionLevel = 6)
  9         {
 10             byte[] result = new byte[] { };
 11 
 12             if (sourceBytes.Length > 0)
 13             {
 14                 try
 15                 {
 16                     using (MemoryStream tempStream = new MemoryStream())
 17                     {
 18                         using (MemoryStream readStream = new MemoryStream(sourceBytes))
 19                         {
 20                             using (ZipOutputStream zipStream = new ZipOutputStream(tempStream))
 21                             {
 22                                 zipStream.Password = password;//設置密碼
 23                                 zipStream.SetLevel(CheckCompressionLevel(compressionLevel));//設置壓縮等級
 24 
 25                                 ZipEntry zipEntry = new ZipEntry("ZipBytes");
 26                                 zipEntry.DateTime = DateTime.Now;
 27                                 zipEntry.Size = sourceBytes.Length;
 28                                 zipStream.PutNextEntry(zipEntry);
 29                                 int readLength = 0;
 30                                 byte[] buffer = new byte[BufferSize];
 31 
 32                                 do
 33                                 {
 34                                     readLength = readStream.Read(buffer, 0, BufferSize);
 35                                     zipStream.Write(buffer, 0, readLength);
 36                                 } while (readLength == BufferSize);
 37 
 38                                 readStream.Close();
 39                                 zipStream.Flush();
 40                                 zipStream.Finish();
 41                                 result = tempStream.ToArray();
 42                                 zipStream.Close();
 43                             }
 44                         }
 45                     }
 46                 }
 47                 catch (System.Exception ex)
 48                 {
 49                     throw new Exception("壓縮位元組數組發生錯誤", ex);
 50                 }
 51             }
 52 
 53             return result;
 54         }
 55 
 56         /// <summary>
 57         /// 解壓位元組數組
 58         /// </summary>
 59         /// <param name="sourceBytes">源位元組數組</param>
 60         /// <param name="password">密碼</param>
 61         /// <returns>解壓後的位元組數組</returns>
 62         public static byte[] DecompressBytes(byte[] sourceBytes, string password = null)
 63         {
 64             byte[] result = new byte[] { };
 65 
 66             if (sourceBytes.Length > 0)
 67             {
 68                 try
 69                 {
 70                     using (MemoryStream tempStream = new MemoryStream(sourceBytes))
 71                     {
 72                         using (MemoryStream writeStream = new MemoryStream())
 73                         {
 74                             using (ZipInputStream zipStream = new ZipInputStream(tempStream))
 75                             {
 76                                 zipStream.Password = password;
 77                                 ZipEntry zipEntry = zipStream.GetNextEntry();
 78 
 79                                 if (zipEntry != null)
 80                                 {
 81                                     byte[] buffer = new byte[BufferSize];
 82                                     int readLength = 0;
 83 
 84                                     do
 85                                     {
 86                                         readLength = zipStream.Read(buffer, 0, BufferSize);
 87                                         writeStream.Write(buffer, 0, readLength);
 88                                     } while (readLength == BufferSize);
 89 
 90                                     writeStream.Flush();
 91                                     result = writeStream.ToArray();
 92                                     writeStream.Close();
 93                                 }
 94                                 zipStream.Close();
 95                             }
 96                         }
 97                     }
 98                 }
 99                 catch (System.Exception ex)
100                 {
101                     throw new Exception("解壓位元組數組發生錯誤", ex);
102                 }
103             }
104             return result;
105         }
View Code

為了測試該類,我寫了一個WinForm程式,界面如下:

SharpZipLib測試界面 可以將文件和文件夾拖放到壓縮列表中,選中壓縮列表中的對象可以按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  
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Razor是MVC框架視圖引擎,我們今天就來說一說Razor視圖引擎。 首先還是來創建一個基礎項目叫Razor來演示。 先來定義一個Model叫Product 接著,來定義一個控制器。 最後,在Views/Home文件夾中創建Index.cshtml文件。 1. 使用模型對象 我們在視圖的第一行使用 ...
  • 舉幾個值類型和引用類型的記憶體配置: 值類型存儲在棧中,引用類型堆里: 1,數組 數組是引用類型,但是數組的元素可以是值類型或引用類型 2. 結構 結構是值類型,簡略的看個例子 struct sample { public int X; public int Y; } simple ss = new ...
  • ASP.NET Core基於 .NET Core 項目模型,它支持構建能夠運行在 Windows、Mac和 Linux 上的跨平臺應用程式。當您構建一個 .Net Core 項目的時候,您可以選擇一種 .NET框架來構建您的應用程式,.NET Framework (CLR)、 .NET Core (... ...
  • LINQ對於筆者來說, 優美而濃縮的代碼讓人震驚. 研究LINQ就是在藝術化自己的代碼. 之前只是走馬觀花學會了基本的語法, 但是經常在CSDN看到令人驚訝自嘆不如的LINQ代碼, 還是讓人羡慕嫉妒恨, 真有一種心血來潮想追趕的衝動. 所以, 還是決定系統的學習一下LINQ. (1.4) LINQ ...
  • WCF如何實現對於Rest支持的呢?弄清這一點是學習Rest WCF的關鍵。 為了實現於對Rest的支持,在 .NET Framework 中,WCF 在 System.ServiceModel.Web 組件中新增了編程模型和一些基礎架構部件。WCF Web編程模型幾個重要類型就是: ...
  • 自古以來,人類的進步都是依賴於工具的進步,從刀耕火種,到使用青銅器,再到現在的科技,每一次都使我們的工作效率提高了無數倍,所以一個好的工具能使我們提高無數倍的工作效率,下麵,我就根據自己簡單的總結一下我們到底要有什麼樣的裝備。這裡現在只寫必須的,因為有太多的好的軟體了,以後再分類補充吧。 一,操作系 ...
  • 在WPF中使用依賴註入的方式創建視圖 0x00 問題的產生 互聯網時代桌面開發真是越來越少了,很多應用都轉到了瀏覽器端和移動智能終端,相應的軟體開發上的新技術應用到桌面開發的文章也很少。我之前主要做WPF,今年開始學習Web應用開發,於是就接觸到了.NET Core,其中的很多概念很值得在桌面開發中 ...
  • 昨天抽空寫了一個wcf的創建和宿主程式的創建文章,下麵也有很多園友給了評論,在此謝謝大家給了我繼續記錄我的摸爬滾打之路信心……抱拳! 上次的文章《我的WCF摸爬滾打之路(1)》中寫到,在測試wcf例子的時候遇到很多稀奇古怪的異常,準備列個專題寫的。無奈學習不深,實在不敢潦草為之。今天就隨便說說吧!說 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...