• .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[]中

  • 相关阅读:
    Linux之网络基础
    Tomcat配置虚拟目录并发布web应用
    Linux之权限管理操作
    Linux之shell编程基础
    Python简介
    Python代码注释 Python零基础入门教程
    Python Pycharm Anacanda 区别
    Python Hello World入门
    Python2.x 和 Python3.x,如何选择?
    数据库课程设计心得【1】
  • 原文地址:https://www.cnblogs.com/rr163/p/4023629.html
Copyright © 2020-2023  润新知