如何使用压缩流

分析问题

  由于网络的带宽限制、硬盘内存空间限制等原因,文件和数据的压缩是程序员经常会遇到的一个需求。针对此.NET类库中提供了对于压缩和解压的支持:GZipStream类型和DeflateStream类型,它们都被定义在System.IO.Compression命名空间下,两者都继承自Stream类型,并且继承了其他流类型操作简便的特性,两个类型实现了基本一致的功能。以下代码展示GZipStream的使用方法。

 

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Compression;
using System.IO;

namespace Test
{
    class Compression
    {
        //缓存数组的长度
        private const int bufferLength = 1024;

        static void Main()
        {
            string test = GetTestString();
            byte[] original = Encoding.Default.GetBytes(test);
            Console.WriteLine("数据的原始长度是:{0}", original.LongLength.ToString());
            //进行压缩
            byte[] compressed = Compress(original);
            Console.WriteLine("压缩后的数据长度是:{0}", compressed.LongLength.ToString());
            //进行解压
            byte[] deCompressed = DeCompress(compressed);
            Console.WriteLine("解压后的数据长度是:{0}", deCompressed.LongLength.ToString());
            Console.WriteLine("解压前后是否相等:{0}", test.Equals(Encoding.Default.GetString(deCompressed)));
            Console.Read();
        }

        //准备测试数据
        static string GetTestString()
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < 1000; i++)
            {
                builder.Append("我是测试数据");
            }
            return builder.ToString();
        }

        //压缩数据
        static byte[] Compress(byte[] data)
        { 
            //压缩入这个内存流
            using (MemoryStream target=new MemoryStream ())
            {
                using (GZipStream gs = new GZipStream(target, CompressionMode.Compress, true))
                { 
                    //把数据写入压缩流
                    WriteAllBytes(gs, data, bufferLength);
                }
                return target.ToArray();
            }
        }

        //解压数据
        static byte[] DeCompress(byte[] data)
        {
            using (MemoryStream source=new MemoryStream (data))
            {
                using (GZipStream gs=new GZipStream (source,CompressionMode.Decompress,true))
                {
                    //从压缩流中读取所有数据
                    return ReadAllBytes(gs, bufferLength);
                }
            }
        }

        //从一个流中读取所有字节
        static byte[] ReadAllBytes(Stream stream, int bufferLength)
        { 
            //读取的缓存
            byte[] buffer = new byte[bufferLength];
            List<byte> result = new List<byte>();
            int read;
            //直至读取结束
            while ((read=stream.Read(buffer,0,bufferLength))>0)
            {
                if (read<bufferLength)
                {
                    byte[] temp = new byte[read];
                    Array.Copy(buffer, temp, read);
                    result.AddRange(temp);

                }
                else
                {
                    result.AddRange(buffer);
                }
            }
            return result.ToArray();
        }

        //把字节写入一个流中
        static void WriteAllBytes(Stream stream, byte[] data, int bufferLength)
        { 
            //写入的缓存
            byte[] buffer = new byte[bufferLength];
            for (long i = 0; i < data.LongLength; i+=bufferLength)
            {
                int length = bufferLength;
                if ((i+bufferLength)>data.LongLength)
                {
                    length = (int)(data.LongLength - i);
                }
                Array.Copy(data, i, buffer, 0, length);
                stream.Write(buffer, 0, length);
            }
        }
    }
}

  以上代码的执行结果是:

  

说明

  .NET提供的DeflateStream类型和GzipStream类型压缩算法并不出色,并且也不能调整压缩率。有些第三方的组件如SharpZipLib实现了更高效的压缩解压算法。

答案

  System.IO.Compression下定义了两个用于压缩数据的类型:DeflateStream和GZipStream,两者都是流类型并且都继承自System.IO.Stream。两个类型的操作和其他流类型一样,非常简便。但相对于一些开源的压缩类库,DeflateStream和GZipStream的算法性能并不高,并且都不支持调整压缩率。

 

   

 

posted on 2014-08-14 11:50  wangjinpeng_study  阅读(313)  评论(0)    收藏  举报

导航