用SharpZipLib(#ZipLib)压缩MemoryStream

来源:互联网 发布:大数据认证有多少 编辑:程序博客网 时间:2024/06/05 19:45
SharpZipLib是一个开源的用C#编写的Zip,GZip,Tar and BZip2库,用于C#的开发.可以在http://www.icsharpcode.net/OpenSource/SharpZipLib/得到.

压缩
为了方便起见,我们添加IO,Text和SharpZipLib名字空间
using System;
using System.IO;
using System.Text;
using ICSharpCode.SharpZipLib.BZip2;
首先,开始压缩.我们创建一个MemoryStream
MemoryStream msCompressed = new MemoryStream();
这次我使用Bzip2,你可用使用zip或tar,然而,他们需要实现一个虚假的文件.选择BZip2而不是Gzip是由于大的数据会压缩的小些.以花费较大的报头为代价.

接下来,我们创建一个BZip2 output stream对象,容纳MemoryStream.
BZip2OutputStream zosCompressed = new BZip2OutputStream(msCompressed);
现在我来解说上面报头的含义.在我的实际测试中使,用GZip时,压缩1字节数据需要28字节的额外报头,那些额外的字节是不能被压缩的.用BZip2时, 需要36字节的额外报头.实际上,用BZip2可以压缩一个12892字节的源文件到2563字节,有大概75%的压缩率.另一个测试是从730字节压缩到429字节,最后一个测试是174字节到161字节.显然,任何压缩需要额外的可用空间.

下面我们将数据写入BZip2OutputStream
string sBuffer = "This represents some data being compressed."
byte[] bytesBuffer = Encoding.ASCII.GetBytes(sBuffer);
zosCompressed.Write(bytesBuffer, 0, bytesBuffer.Length);
zosCompressed.Finalize();
zosCompressed.Close();

由于要用到IO和stream方法,要使用字节数组替代字符串.所以我们用字节数组作为输出,然后将压缩的流写入内存流.
bytesBuffer = msCompressed.ToArray();
string sCompressed = Encoding.ASCII.GetString(bytesBuffer);

这样内存流中包含了压缩过的数据,我们将数据用字符数组输出,然后转换成字符串.要注意,这个字符串是乱码,不可读的.如果你想查看数据, 我用的方法是把它转换为Base64编码的数据,但是这样会增加大小.运行程序使43字节的未压缩数据变成74字节的压缩数据,如果用base 64编码,会得到100字节的结果:
QlpoOTFBWSZTWZxkIpsAAAMTgEABBAA+49wAIAAxTTIxMTEImJhNNDIbvQ
aWyYEHiwN49LdoKNqKN2C9ZUG5+LuSKcKEhOMhFNg=

解压缩
MemoryStream msUncompressed =
new MemoryStream(Encoding.ASCII.GetBytes(sCompressed));
BZip2InputStream zisUncompressed = new BZip2InputStream(msUncompressed);
bytesBuffer = new byte[zisUncompressed.Length];
zisUncompressed.Read(bytesBuffer, 0, bytesBuffer.Length);
zisUncompressed.Close();
msUncompressed.Close();
string sUncompressed = Encoding.ASCII.GetString(bytesBuffer);

这样sUncompressed将被解压到原始的字符串.文件也是相同的原理.