.net 利用 GZipStream 压缩和解压缩

1.GZipStream 类

 

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

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

2.压缩byte[]

        /// <summary>
        /// 压缩数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] Compress(byte[] data)
        {
            MemoryStream ms = new MemoryStream();
            GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress);
            zipStream.Write(data, 0, data.Length);//将数据压缩并写到基础流中
            zipStream.Close();
            return ms.ToArray();
        }

3.解压byte[]

        /// 解压数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] Decompress(byte[] data)
        {
            MemoryStream srcMs = new MemoryStream(data);
            GZipStream zipStream = new GZipStream(srcMs, CompressionMode.Decompress);
            MemoryStream ms = new MemoryStream();
            byte[] bytes = new byte[40960];
            int n;
            while ((n = zipStream.Read(bytes, 0, bytes.Length)) > 0)
            {
                ms.Write(bytes, 0, n);
            }
            zipStream.Close();
            return ms.ToArray();
        }

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

/// <summary>
        /// 将指定的字节数组压缩,并写入到目标文件
        /// </summary>
        /// <param name="srcBuffer">指定的源字节数组</param>
        /// <param name="destFile">指定的目标文件</param>
        public static void CompressData(byte[] srcBuffer, string destFile)
        {
            FileStream destStream = null;
            GZipStream compressedStream = null;
            try
            {
                //打开文件流
                destStream = new FileStream(destFile, FileMode.OpenOrCreate, FileAccess.Write);
                //指定压缩的目的流(这里是文件流)
                compressedStream = new GZipStream(destStream, CompressionMode.Compress, true);
                //往目的流中写数据,而流将数据写到指定的文件
                compressedStream.Write(srcBuffer, 0, srcBuffer.Length);
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("压缩数据写入文件{0}时发生错误", destFile), ex);
            }
            finally
            {
                // Make sure we allways close all streams               
                if (null != compressedStream)
                {
                    compressedStream.Close();
                    compressedStream.Dispose();
                }

                if (null != destStream)
                    destStream.Close();
            }
        }

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

/// <summary>
        /// 将指定的文件解压,返回解压后的数据
        /// </summary>
        /// <param name="srcFile">指定的源文件</param>
        /// <returns>解压后得到的数据</returns>
        public static byte[] DecompressData(string srcFile)
        {
            if (false == File.Exists(srcFile))
                throw new FileNotFoundException(String.Format("找不到指定的文件{0}", srcFile));
            FileStream sourceStream = null;
            GZipStream decompressedStream = null;
            byte[] quartetBuffer = null;
            try
            {
                sourceStream = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.Read);

                decompressedStream = new GZipStream(sourceStream, CompressionMode.Decompress, true);

                // Read the footer to determine the length of the destiantion file
                //GZIP文件格式说明:
                //10字节的头,包含幻数、版本号以及时间戳
                //可选的扩展头,如原文件名
                //文件体,包括DEFLATE压缩的数据
                //8字节的尾注,包括CRC-32校验和以及未压缩的原始数据长度(4字节) 文件大小不超过4G

                //为Data指定byte的长度,故意开大byte数据的范围
                //读取未压缩的原始数据长度
                quartetBuffer = new byte[4];
                long position = sourceStream.Length - 4;
                sourceStream.Position = position;
                sourceStream.Read(quartetBuffer, 0, 4);

                int checkLength = BitConverter.ToInt32(quartetBuffer, 0);
                byte[] data;
                if (checkLength <= sourceStream.Length)
                {
                    data = new byte[Int16.MaxValue];
                }
                else
                {
                    data = new byte[checkLength + 100];
                }
                //每100byte从解压流中读出数据,并将读出的数据Copy到Data byte[]中,这样就完成了对数据的解压
                byte[] buffer = new byte[100];

                sourceStream.Position = 0;

                int offset = 0;
                int total = 0;

                while (true)
                {
                    int bytesRead = decompressedStream.Read(buffer, 0, 100);

                    if (bytesRead == 0)
                        break;

                    buffer.CopyTo(data, offset);

                    offset += bytesRead;
                    total += bytesRead;
                }
                //剔除多余的byte
                byte[] actualdata = new byte[total];

                for (int i = 0; i < total; i++)
                    actualdata[i] = data[i];

                return actualdata;
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("从文件{0}解压数据时发生错误", srcFile), ex);
            }
            finally
            {
                if (sourceStream != null)
                    sourceStream.Close();

                if (decompressedStream != null)
                    decompressedStream.Close();
            }
        }

6.小结

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

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

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

byte[]中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值