ASP.NET 中的压缩和解压

作者:vkvi 来源:ITPOW(原创) 日期:2007-12-10

在 ASP.NET 中有两个类:DeflateStream 和 GZipStream 用于处理压缩和解压缩,这两个类分别使用的是 DEFLATE 和 gzip 压缩算法,这两个算法被一些压缩软件支持,比如 WinRAR 就支持 gzip。这两个类的名称空间均为:

System.IO.Compression

这两个类在应用上完全一致,所以我们本节只讲解其中一个类的用法,要使用另一个类,只需要把源代码中的类名称替换就可以了。

  • 压缩步骤:往压缩流中写入未压缩的数据->关闭压缩流->从内存流中读取压缩了的数据
  • 解压步骤:往内存流中写入压缩了的数据->从压缩流中读取解压了的数据

可以看到压缩流(DeflateStream 或 GZipStream)与未压缩或解压了的数据打交道,而内存流(MemoryStream)与压缩了的数据打交道。

压缩代码:

        //文件流
        FileStream reader;
        reader = File.Open("D:\\foo.txt", FileMode.Open);
        FileStream writer;
        writer = File.Create("D:\\dest.gzip");
       
        //压缩相关的流
        MemoryStream ms = new MemoryStream();
        GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
       
        //往压缩流中写数据
        byte[] sourceBuffer = new byte[reader.Length];
        reader.Read(sourceBuffer, 0, sourceBuffer.Length);
        zipStream.Write(sourceBuffer, 0, sourceBuffer.Length);
       
        //一定要在内存流读取之前关闭压缩流
        zipStream.Close();
        zipStream.Dispose();
       
        //从内存流中读数据
        ms.Position = 0; //注意,不要遗漏此句
        byte[] destBuffer = new byte[ms.Length];
        ms.Read(destBuffer, 0, destBuffer.Length);
        writer.Write(destBuffer, 0, destBuffer.Length);
       
        //关闭并释放内存流
        ms.Close();
        ms.Dispose();
       
        //关闭并释放文件流
        writer.Close();
        writer.Dispose();
        reader.Close();
        reader.Dispose();

两点注意:

  • 一定要在内存流读取之前关闭压缩流。
  • 从内存中读数据时指定位置 0 不可少。

解压代码:

        //文件流
        FileStream reader;
        reader = File.Open("D:\\dest.gzip", FileMode.Open);
        FileStream writer;
        writer = File.Create("D:\\dest.txt");
       
        //解压相关的流,同时向内存流中写数据
        byte[] sourceBuffer = new byte[reader.Length];
        reader.Read(sourceBuffer, 0, sourceBuffer.Length);
        MemoryStream ms = new MemoryStream(sourceBuffer);
        GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress, true);
        
        byte[] destBuffer = new byte[1];
        while (zipStream.Read(destBuffer, 0, destBuffer.Length) > 0)
        {
            writer.Write(destBuffer, 0, destBuffer.Length);
        }
       
        //释放并关闭解压流和内存流
        zipStream.Close();
        zipStream.Dispose();
        ms.Close();
        ms.Dispose();
       
        //关闭并释放文件流
        writer.Close();
        writer.Dispose();
        reader.Close();
        reader.Dispose();

一点注意

  • 对 GZipStream 使用 Position 和 Length 总是会产生异常。

词汇

  • DEFLATE 是同时使用了 LZ77 算法与哈夫曼编码的一个无损数据压缩算法。它最初是由 Phil Katz 为他的 PKZIP 归档工具第二版所定义的,后来定义在 RFC1951 规范中。
  • gzip 的基础是 DEFLATE,DEFLATE 是 LZ77 与哈夫曼编码的一个组合体。DEFLATE 最初是作为 LZW 以及其它受专利保护的数据压缩算法的替代版本而设计的,当时那些专利限制了 compress 以及其它一些流行的归档工具的应用。

相关阅读

相关文章