程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 壓縮庫SharpZipLib的應用,壓縮庫sharpziplib

壓縮庫SharpZipLib的應用,壓縮庫sharpziplib

編輯:C#入門知識

壓縮庫SharpZipLib的應用,壓縮庫sharpziplib


   SharpZipLib是一個開源的C#壓縮解壓庫,應用非常廣泛。就像用ADO.NET操作數據庫要打開連接、執行命令、關閉連接等多個步驟一樣,用SharpZipLib進行壓縮和解壓也需要多個步驟。除了初學者會用原始的方法做一步一步完成,實際開發的時候都會進行更易用的封裝。這裡分享我對SharpZipLib的封裝,支持對文件和流進行壓縮和解壓操作,支持多個文件和文件夾壓縮,支持設置備注和密碼。     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  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved