压缩文本、字节或者文件的压缩辅助类-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:406590790@qq.com 
QQ交流:406590790 
关于作者:高级工程师、信息系统项目管理师、DBA。专注于微软平台项目架构、管理和企业解决方案,多年项目开发与管理经验,曾多次组织并开发多个大型项目,在面向对象、面向服务以及数据库领域有一定的造诣。现主要从事基于 RDIFramework.NET 框架的技术开发、咨询工作,主要服务于金融、医疗卫生、铁路、电信、物流、物联网、制造、零售等行业。 
如有问题或建议,请多多赐教! 
本文版权归作者和CNBLOGS博客共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过邮箱或QQ 联系我,非常感谢。