壓縮文本、字節或者文件的壓縮輔助類-GZipHelper 歡迎收藏

壓縮文本、字節或者文件的壓縮輔助類-GZipHelper 歡迎收藏

  下面爲大家介紹一.NET下輔助公共類GZipHelper,該工具類主要作用是對文本、字符、文件等進行壓縮與解壓。該類主要使用命名空間:System.IO.Compression下的GZipStream類來實現。  此類表示 GZip 數據格式,它使用無損壓縮和解壓縮文件的行業標準算法。這種格式包括一個檢測數據損壞的循環冗餘校驗值。GZip 數據格式使用的算法與 DeflateStream 類的算法相同,但它可以擴展以使用其他壓縮格式。這種格式可以通過不涉及專利使用權的方式輕鬆實現。gzip 的格式可以從 RFC 1952“GZIP file format specification 4.3(GZIP 文件格式規範 4.3)GZIP file format specification 4.3(GZIP 文件格式規範 4.3)”中獲得。此類不能用於壓縮大於 4 GB 的文件。

  一、屬性

BaseStream       獲取對基礎流的引用。 
CanRead        獲取一個值,該值指示流是否支持在解壓縮文件的過程中讀取文件。 (重寫 Stream..::.CanRead。) 
CanSeek        獲取一個值,該值指示流是否支持查找。 (重寫 Stream..::.CanSeek。) 
CanTimeout       獲取一個值,該值確定當前流是否可以超時。 (繼承自 Stream。) 
CanWrite         獲取一個值,該值指示流是否支持寫入。 (重寫 Stream..::.CanWrite。) 
Length          不支持,並且總是引發 NotSupportedException。 (重寫 Stream..::.Length。) 
Position         不支持,並且總是引發 NotSupportedException。 (重寫 Stream..::.Position。) 
ReadTimeout       獲取或設置一個值(以毫秒爲單位),該值確定流在超時前嘗試讀取多長時間。 (繼承自 Stream。) 
WriteTimeout      獲取或設置一個值(以毫秒爲單位),該值確定流在超時前嘗試寫入多長時間。 (繼承自 Stream。)

二、方法

BeginRead         開始異步讀操作。 (重寫 Stream..::.BeginRead(array<Byte>[]()[], Int32, Int32, AsyncCallback, Object)。) 
BeginWrite        開始異步寫操作。 (重寫 Stream..::.BeginWrite(array<Byte>[]()[], Int32, Int32, AsyncCallback, Object)。) 
Close           關閉當前流並釋放與之關聯的所有資源(如套接字和文件句柄)。 (繼承自 Stream。) 
CreateObjRef       創建一個對象,該對象包含生成用於與遠程對象進行通信的代理所需的全部相關信息。 (繼承自 MarshalByRefObject。) 
Dispose           已重載。 
EndRead           等待掛起的異步讀取完成。 (重寫 Stream..::.EndRead(IAsyncResult)。) 
EndWrite          處理異步寫入的結束。 (重寫 Stream..::.EndWrite(IAsyncResult)。) 
Flush            將當前 GZipStream 對象的內部緩衝區的內容刷新到基礎流。 (重寫 Stream..::.Flush()()()。) 
GetHashCode        用作特定類型的哈希函數。 (繼承自 Object。) 
GetLifetimeService     檢索控制此實例的生存期策略的當前生存期服務對象。 (繼承自 MarshalByRefObject。) 
InitializeLifetimeService  獲取控制此實例的生存期策略的生存期服務對象。 (繼承自 MarshalByRefObject。) 
MemberwiseClone      已重載。 
Read             將若干解壓縮的字節讀入指定的字節數組。 (重寫 Stream..::.Read(array<Byte>[]()[], Int32, Int32)。) 
ReadByte          從流中讀取一個字節,並將流內的位置向前推進一個字節,或者如果已到達流的末尾,則返回 -1。 (繼承自 Stream。) 
Seek             此屬性不受支持,並且總是引發 NotSupportedException。 (重寫 Stream..::.Seek(Int64, SeekOrigin)。) 
SetLength         此屬性不受支持,並且總是引發 NotSupportedException。 (重寫 Stream..::.SetLength(Int64)。) 
Write            從指定的字節數組中將壓縮的字節寫入基礎流。 (重寫 Stream..::.Write(array<Byte>[]()[], Int32, Int32)。) 
WriteByte         將一個字節寫入流內的當前位置,並將流內的位置向前推進一個字節。 (繼承自 Stream。) 

使用原生的方法進行壓縮解壓文件實例代碼:

 

[csharp] view plaincopy
 
  1. /// <summary>  
  2.  /// 壓縮文件  
  3.  /// </summary>  
  4.  /// <param name="fileName">文件名(全路徑)</param>  
  5.  /// <param name="data">需要壓縮的字符串</param>  
  6.  public void CompressFile(string fileName, string data)  
  7.  {         
  8.      FileStream fstream = new FileStream(fileName, FileMode.Create, FileAccess.Write);  
  9.      GZipStream gstream = new GZipStream(fstream, CompressionMode.Compress);  
  10.      StreamWriter swriter = new StreamWriter(gstream);  
  11.      swriter.Write(data);  
  12.      swriter.Close();  
  13.      gstream.Close();  
  14.      fstream.Close();  
  15.  }  
  16.  /// <summary>  
  17.  /// 解壓縮  
  18.  /// </summary>  
  19.  /// <param name="fileName">文件名(全路徑)</param>  
  20.  /// <returns></returns>  
  21.  public string DecompressFile(string fileName)  
  22.  {  
  23.      string cstring="";  
  24.      FileStream fstream = new FileStream(fileName, FileMode.Open, FileAccess.Read);  
  25.      GZipStream gstream = new GZipStream(fstream, CompressionMode.Decompress);  
  26.      StreamReader reader = new StreamReader(gstream);  
  27.      cstring=reader.ReadToEnd();  
  28.      reader.Close();  
  29.      gstream.Close();  
  30.      fstream.Close();  
  31.      return cstring;  
  32.  }  

 

GZipHelper公共類就是以GZipStream類爲基礎做的對常用解壓縮進行的封裝。GZipHelper類圖如下所示:

 GZipHelper公共類完整源碼:

 

[csharp] view plaincopy
 
  1. using System;  
  2. using System.IO;  
  3. using System.IO.Compression;  
  4. using System.Text;  
  5.    
  6. namespace RDIFramework.Utilities  
  7. {  
  8.     /// <summary>  
  9.     /// 壓縮文本、字節或者文件的壓縮輔助類  
  10.     /// </summary>  
  11.     public class GZipHelper  
  12.     {  
  13.         /// <summary>  
  14.         /// 壓縮字符串  
  15.         /// </summary>  
  16.         /// <param name="text"></param>  
  17.         /// <returns></returns>  
  18.         public static string Compress(string text)  
  19.         {  
  20.             // convert text to bytes  
  21.             byte[] buffer = Encoding.UTF8.GetBytes(text);  
  22.             // get a stream  
  23.             MemoryStream ms = new MemoryStream();  
  24.             // get ready to zip up our stream  
  25.             using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))  
  26.             {  
  27.                 // compress the data into our buffer  
  28.                 zip.Write(buffer, 0, buffer.Length);  
  29.             }  
  30.             // reset our position in compressed stream to the start  
  31.             ms.Position = 0;  
  32.             // get the compressed data  
  33.             byte[] compressed = ms.ToArray();  
  34.             ms.Read(compressed, 0, compressed.Length);  
  35.             // prepare final data with header that indicates length  
  36.             byte[] gzBuffer = new byte[compressed.Length + 4];  
  37.             //copy compressed data 4 bytes from start of final header  
  38.             System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);  
  39.             // copy header to first 4 bytes  
  40.             System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);  
  41.             // convert back to string and return  
  42.             return Convert.ToBase64String(gzBuffer);  
  43.         }  
  44.    
  45.         /// <summary>  
  46.         /// 解壓字符串  
  47.         /// </summary>  
  48.         /// <param name="compressedText"></param>  
  49.         /// <returns></returns>  
  50.         public static string Uncompress(string compressedText)  
  51.         {  
  52.             // get string as bytes  
  53.             byte[] gzBuffer = Convert.FromBase64String(compressedText);  
  54.             // prepare stream to do uncompression  
  55.             MemoryStream ms = new MemoryStream();  
  56.             // get the length of compressed data  
  57.             int msgLength = BitConverter.ToInt32(gzBuffer, 0);  
  58.             // uncompress everything besides the header  
  59.             ms.Write(gzBuffer, 4, gzBuffer.Length - 4);  
  60.             // prepare final buffer for just uncompressed data  
  61.             byte[] buffer = new byte[msgLength];  
  62.             // reset our position in stream since we're starting over  
  63.             ms.Position = 0;  
  64.             // unzip the data through stream  
  65.             GZipStream zip = new GZipStream(ms, CompressionMode.Decompress);  
  66.             // do the unzip  
  67.             zip.Read(buffer, 0, buffer.Length);  
  68.             // convert back to string and return  
  69.             return Encoding.UTF8.GetString(buffer);  
  70.         }  
  71.    
  72.         public static T GZip<T>(Stream stream, CompressionMode mode) where T : Stream  
  73.         {  
  74.             byte[] writeData = new byte[4096];  
  75.             T ms = default(T);  
  76.             using (Stream sg = new GZipStream(stream, mode))  
  77.             {  
  78.                 while (true)  
  79.                 {  
  80.                     Array.Clear(writeData, 0, writeData.Length);  
  81.                     int size = sg.Read(writeData, 0, writeData.Length);  
  82.                     if (size > 0)  
  83.                     {  
  84.                         ms.Write(writeData, 0, size);  
  85.                     }  
  86.                     else  
  87.                     {  
  88.                         break;  
  89.                     }  
  90.                 }  
  91.                 return ms;  
  92.             }  
  93.         }  
  94.    
  95.         /// <summary>  
  96.         /// 壓縮字節  
  97.         /// </summary>  
  98.         /// <param name="bytData"></param>  
  99.         /// <returns></returns>  
  100.         public static byte[] Compress(byte[] bytData)  
  101.         {  
  102.             using (MemoryStream stream = GZip<MemoryStream>(new MemoryStream(bytData), CompressionMode.Compress))  
  103.             {  
  104.                 return stream.ToArray();  
  105.             }  
  106.         }  
  107.    
  108.         /// <summary>  
  109.         /// 解壓字節  
  110.         /// </summary>  
  111.         /// <param name="bytData"></param>  
  112.         /// <returns></returns>  
  113.         public static byte[] Decompress(byte[] bytData)  
  114.         {  
  115.             using (MemoryStream stream = GZip<MemoryStream>(new MemoryStream(bytData), CompressionMode.Decompress))  
  116.             {  
  117.                 return stream.ToArray();  
  118.             }  
  119.         }  
  120.    
  121.         /// <summary>  
  122.         /// 壓縮文件  
  123.         /// </summary>  
  124.         /// <param name="sourceFile">源文件</param>  
  125.         /// <param name="destinationFile">目標文件</param>  
  126.         public static void CompressFile(string sourceFile, string destinationFile)  
  127.         {  
  128.             if (File.Exists(sourceFile) == false//判斷文件是否存在  
  129.                 throw new FileNotFoundException();  
  130.             if (File.Exists(destinationFile) == false//判斷目標文件文件是否存在  
  131.                 FileHelper.FileDel(destinationFile);  
  132.             //創建文件流和字節數組  
  133.             byte[] buffer = null;  
  134.             FileStream sourceStream = null;  
  135.             FileStream destinationStream = null;  
  136.             GZipStream compressedStream = null;  
  137.             try  
  138.             {  
  139.                 sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);  
  140.                 buffer = new byte[sourceStream.Length];  
  141.                 //把文件流存放到字節數組中  
  142.                 int checkCounter = sourceStream.Read(buffer, 0, buffer.Length);  
  143.                 if (checkCounter != buffer.Length)  
  144.                 {  
  145.                     throw new ApplicationException();  
  146.                 }  
  147.                 destinationStream = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write);  
  148.                 //創建GzipStream實例,寫入壓縮的文件流  
  149.                 compressedStream = new GZipStream(destinationStream, CompressionMode.Compress, true);  
  150.                 compressedStream.Write(buffer, 0, buffer.Length);  
  151.             }  
  152.             finally  
  153.             {  
  154.                 // Make sure we allways close all streams  
  155.                 if (sourceStream != null)  
  156.                 { sourceStream.Close(); }  
  157.                 if (compressedStream != null)  
  158.                 { compressedStream.Close(); }  
  159.                 if (destinationStream != null)  
  160.                 { destinationStream.Close(); }  
  161.             }  
  162.         }  
  163.    
  164.         /// <summary>  
  165.         /// 解壓文件  
  166.         /// </summary>  
  167.         /// <param name="sourceFile">源文件</param>  
  168.         /// <param name="destinationFile">目標文件</param>  
  169.         public static void DecompressFile(string sourceFile, string destinationFile)  
  170.         {  
  171.             if (!File.Exists(sourceFile))  
  172.             {  
  173.                 throw new FileNotFoundException();  
  174.             }  
  175.             FileStream stream = null;  
  176.             FileStream stream2 = null;  
  177.             GZipStream stream3 = null;  
  178.             byte[] buffer = null;  
  179.             try  
  180.             {  
  181.                 stream = new FileStream(sourceFile, FileMode.Open);  
  182.                 stream3 = new GZipStream(stream, CompressionMode.Decompress, true);  
  183.                 buffer = new byte[4];  
  184.                 int num = ((int)stream.Length) - 4;  
  185.                 stream.Position = num;  
  186.                 stream.Read(buffer, 0, 4);  
  187.                 stream.Position = 0L;  
  188.                 byte[] buffer2 = new byte[BitConverter.ToInt32(buffer, 0) + 100];  
  189.                 int offset = 0;  
  190.                 int count = 0;  
  191.                 while (true)  
  192.                 {  
  193.                     int num5 = stream3.Read(buffer2, offset, 100);  
  194.                     if (num5 == 0)  
  195.                     {  
  196.                         break;  
  197.                     }  
  198.                     offset += num5;  
  199.                     count += num5;  
  200.                 }  
  201.                 stream2 = new FileStream(destinationFile, FileMode.Create);  
  202.                 stream2.Write(buffer2, 0, count);  
  203.                 stream2.Flush();  
  204.             }  
  205.             finally  
  206.             {  
  207.                 if (stream != null)  
  208.                 {  
  209.                     stream.Close();  
  210.                 }  
  211.                 if (stream3 != null)  
  212.                 {  
  213.                     stream3.Close();  
  214.                 }  
  215.                 if (stream2 != null)  
  216.                 {  
  217.                     stream2.Close();  
  218.                 }  
  219.             }  
  220.         }  
  221.     }  
  222. }  

   

參考資料

MSDN GZipStream 類介紹

作者: EricHu 
出處:http://blog.rdiframework.net/
Email:[email protected] 
QQ交流:406590790 
關於作者:高級工程師、信息系統項目管理師、DBA。專注於微軟平臺項目架構、管理和企業解決方案,多年項目開發與管理經驗,曾多次組織並開發多個大型項目,在面向對象、面向服務以及數據庫領域有一定的造詣。現主要從事基於 RDIFramework.NET 框架的技術開發、諮詢工作,主要服務於金融、醫療衛生、鐵路、電信、物流、物聯網、製造、零售等行業。 
如有問題或建議,請多多賜教! 
本文版權歸作者和CNBLOGS博客共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,如有問題,可以通過郵箱或QQ 聯繫我,非常感謝。

發佈了6 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章