zoukankan      html  css  js  c++  java
  • .net 利用 GZipStream 压缩和解压缩

    1.GZipStream 类

     

    此类在 .NET Framework 2.0 版中是新增的。

    提供用于压缩和解压缩流的方法和属性

    2.压缩byte[]

    C#代码  收藏代码
    1. /// <summary>  
    2. /// 压缩数据  
    3. /// </summary>  
    4. /// <param name="data"></param>  
    5. /// <returns></returns>  
    6. public byte[] Compress(byte[] data)  
    7. {  
    8.     MemoryStream ms = new MemoryStream();  
    9.     GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress);  
    10.     zipStream.Write(data, 0, data.Length);//将数据压缩并写到基础流中  
    11.     zipStream.Close();  
    12.     return ms.ToArray();  
    13. }  

    3.解压byte[]

    C#代码  收藏代码
    1. /// 解压数据  
    2. /// </summary>  
    3. /// <param name="data"></param>  
    4. /// <returns></returns>  
    5. public byte[] Decompress(byte[] data)  
    6. {  
    7.     MemoryStream srcMs = new MemoryStream(data);  
    8.     GZipStream zipStream = new GZipStream(srcMs, CompressionMode.Decompress);  
    9.     MemoryStream ms = new MemoryStream();  
    10.     byte[] bytes = new byte[40960];  
    11.     int n;  
    12.     while ((n = zipStream.Read(bytes, 0, bytes.Length)) > 0)  
    13.     {  
    14.         ms.Write(bytes, 0, n);  
    15.     }  
    16.     zipStream.Close();  
    17.     return ms.ToArray();  
    18. }  

    4.压缩byte[]数据,存放到文件中

    C#代码  收藏代码
    1. /// <summary>  
    2.         /// 将指定的字节数组压缩,并写入到目标文件  
    3.         /// </summary>  
    4.         /// <param name="srcBuffer">指定的源字节数组</param>  
    5.         /// <param name="destFile">指定的目标文件</param>  
    6.         public static void CompressData(byte[] srcBuffer, string destFile)  
    7.         {  
    8.             FileStream destStream = null;  
    9.             GZipStream compressedStream = null;  
    10.             try  
    11.             {  
    12.                 //打开文件流  
    13.                 destStream = new FileStream(destFile, FileMode.OpenOrCreate, FileAccess.Write);  
    14.                 //指定压缩的目的流(这里是文件流)  
    15.                 compressedStream = new GZipStream(destStream, CompressionMode.Compress, true);  
    16.                 //往目的流中写数据,而流将数据写到指定的文件  
    17.                 compressedStream.Write(srcBuffer, 0, srcBuffer.Length);  
    18.             }  
    19.             catch (Exception ex)  
    20.             {  
    21.                 throw new Exception(String.Format("压缩数据写入文件{0}时发生错误", destFile), ex);  
    22.             }  
    23.             finally  
    24.             {  
    25.                 // Make sure we allways close all streams                 
    26.                 if (null != compressedStream)  
    27.                 {  
    28.                     compressedStream.Close();  
    29.                     compressedStream.Dispose();  
    30.                 }  
    31.   
    32.                 if (null != destStream)  
    33.                     destStream.Close();  
    34.             }  
    35.         }  

    5.解压文件,得到byte[]数据

    C#代码  收藏代码
    1. /// <summary>  
    2.         /// 将指定的文件解压,返回解压后的数据  
    3.         /// </summary>  
    4.         /// <param name="srcFile">指定的源文件</param>  
    5.         /// <returns>解压后得到的数据</returns>  
    6.         public static byte[] DecompressData(string srcFile)  
    7.         {  
    8.             if (false == File.Exists(srcFile))  
    9.                 throw new FileNotFoundException(String.Format("找不到指定的文件{0}", srcFile));  
    10.             FileStream sourceStream = null;  
    11.             GZipStream decompressedStream = null;  
    12.             byte[] quartetBuffer = null;  
    13.             try  
    14.             {  
    15.                 sourceStream = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read);  
    16.   
    17.                 decompressedStream = new GZipStream(sourceStream, CompressionMode.Decompress, true);  
    18.   
    19.                 // Read the footer to determine the length of the destiantion file  
    20.                 //GZIP文件格式说明:  
    21.                 //10字节的头,包含幻数、版本号以及时间戳   
    22.                 //可选的扩展头,如原文件名   
    23.                 //文件体,包括DEFLATE压缩的数据   
    24.                 //8字节的尾注,包括CRC-32校验和以及未压缩的原始数据长度(4字节) 文件大小不超过4G   
    25.   
    26.                 //为Data指定byte的长度,故意开大byte数据的范围  
    27.                 //读取未压缩的原始数据长度  
    28.                 quartetBuffer = new byte[4];  
    29.                 long position = sourceStream.Length - 4;  
    30.                 sourceStream.Position = position;  
    31.                 sourceStream.Read(quartetBuffer, 0, 4);  
    32.   
    33.                 int checkLength = BitConverter.ToInt32(quartetBuffer, 0);  
    34.                 byte[] data;  
    35.                 if (checkLength <= sourceStream.Length)  
    36.                 {  
    37.                     data = new byte[Int16.MaxValue];  
    38.                 }  
    39.                 else  
    40.                 {  
    41.                     data = new byte[checkLength + 100];  
    42.                 }  
    43.                 //每100byte从解压流中读出数据,并将读出的数据Copy到Data byte[]中,这样就完成了对数据的解压  
    44.                 byte[] buffer = new byte[100];  
    45.   
    46.                 sourceStream.Position = 0;  
    47.   
    48.                 int offset = 0;  
    49.                 int total = 0;  
    50.   
    51.                 while (true)  
    52.                 {  
    53.                     int bytesRead = decompressedStream.Read(buffer, 0, 100);  
    54.   
    55.                     if (bytesRead == 0)  
    56.                         break;  
    57.   
    58.                     buffer.CopyTo(data, offset);  
    59.   
    60.                     offset += bytesRead;  
    61.                     total += bytesRead;  
    62.                 }  
    63.                 //剔除多余的byte  
    64.                 byte[] actualdata = new byte[total];  
    65.   
    66.                 for (int i = 0; i < total; i++)  
    67.                     actualdata[i] = data[i];  
    68.   
    69.                 return actualdata;  
    70.             }  
    71.             catch (Exception ex)  
    72.             {  
    73.                 throw new Exception(String.Format("从文件{0}解压数据时发生错误", srcFile), ex);  
    74.             }  
    75.             finally  
    76.             {  
    77.                 if (sourceStream != null)  
    78.                     sourceStream.Close();  
    79.   
    80.                 if (decompressedStream != null)  
    81.                     decompressedStream.Close();  
    82.             }  
    83.         }  

    6.小结

    压缩,解压都用GZipStream,操作的对象时普通流MemoryStream,不同的是:

    压缩是将btye[]型的数据写入GZipStream中,而解压的时候是将GzipStream中的数据写入到byte[]中,并将读出的数据写入到MemoryStream后一次性输出

            压缩到文件与压缩成byte[]不同的是压缩到文件利用到了FileStream将流写到文件,解压Gzip文件,需要根据文件的规则进行:后4位记录未压缩前的长度,根据该长度可以将解压出来的文件存放到稍大的byte[]中

  • 相关阅读:
    SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问
    谷歌浏览器扩展程序manifest.json参数详解
    获取天气api
    UVA 10385 Duathlon
    UVA 10668 Expanding Rods
    UVALIVE 3891 The Teacher's Side of Math
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 11210 Chinese Mahjong
    UVA 11384 Help is needed for Dexter
  • 原文地址:https://www.cnblogs.com/rr163/p/4023629.html
Copyright © 2011-2022 走看看