首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

.net 利用 GZipStream 压缩和好压缩

2012-08-25 
.net 利用 GZipStream 压缩和解压缩?.net 利用 GZipStream 压缩和解压缩1.GZipStream 类?此类在 .NET Fram

.net 利用 GZipStream 压缩和解压缩

?

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

热点排行