如下两个方法~ 一个压缩,一个解压缩。 都是直接调用 System.IO.Compression.GZipStream 类。
压缩正常,可是解压缩的方法确莫名奇妙的出错。
1public void Compress(System.IO.Stream orgStream, System.IO.Stream cmpStream)
2 {
3 System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(cmpStream, System.IO.Compression.CompressionMode.Compress);
4
5 byte[] buffer = new byte[100];
6 int offset = 0;
7 while (true)
8 {
9 int bytesRead = orgStream.Read(buffer, offset, 100);
10 if (bytesRead == 0)
11 {
12 break;
13 }
14 zipStream.Write(buffer, 0, bytesRead);
15 }
16 }
1 public void DeCompress(System.IO.Stream cmpStream, System.IO.Stream orgStream)
2 {
3 System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(cmpStream, System.IO.Compression.CompressionMode.Decompress);
4 byte[] buffer = new byte[100];
5 int offset = 0;
6 while (true)
7 { //cmpStream明明有数据,但是这里个bytesRead第一次循环有时会为0,造成解压缩失败,有时又可以。怎么回事?????
8 int bytesRead = zipStream.Read(buffer, offset, 100);
9 if (bytesRead == 0)
10 {
11 break;
12 }
13 orgStream.Write(buffer, 0, bytesRead);
14 }
15 }
不知道是不是System.IO.Compression.GZipStream的使用方法不对,求助园子里的朋友.
====================================================
补充一下修改后的完整代码,这个问题还是没解决,怀疑是GzipStream本身有Bug,发布出来希望有同样遇到问题的朋友能提点一下~
2 public void Compress(System.IO.Stream orgStream, System.IO.Stream cmpStream)
3 {
4 System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(cmpStream, System.IO.Compression.CompressionMode.Compress);
5 BinaryWriter writer = new BinaryWriter(zipStream);
6 BinaryReader reader = new BinaryReader(orgStream);
7 while ( true )
8 {
9 byte [] buffer = reader.ReadBytes( 100 );
10 if (buffer == null || buffer.Length < 1 )
11 break ;
12 writer.Write(buffer);
13 }
14 }
15 // 解压缩
16 public void DeCompress(System.IO.Stream cmpStream, System.IO.Stream orgStream)
17 {
18 System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(cmpStream, System.IO.Compression.CompressionMode.Decompress);
19 BinaryReader reader = new BinaryReader(zipStream);
20 BinaryWriter writer = new BinaryWriter(orgStream);
21 while ( true )
22 {
23 byte [] buffer = reader.ReadBytes( 100 );
24 if (buffer == null || buffer.Length < 1 )
25 break ;
26 writer.Write(buffer);
27 }
28 }
29 // 执行压缩
30 private void button1_Click( object sender, EventArgs e)
31 {
32 System.IO.FileStream targetstream = new System.IO.FileStream( this .txt_SelFile.Text, System.IO.FileMode.Open);
33 System.IO.FileStream saveStream = new System.IO.FileStream( this .txt_SaveTo.Text, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read);
34 CompressionHelper.Compress(CompressionHelper.CompressionMode.GZip,targetstream, saveStream);
35 targetstream.Close();
36 saveStream.Close();
37 }
38 // 执行解压缩
39 private void button2_Click( object sender, EventArgs e)
40 {
41 System.IO.FileStream targetstream = new System.IO.FileStream( this .txt_SelFile.Text, System.IO.FileMode.Open);
42 System.IO.FileStream saveStream = new System.IO.FileStream( this .txt_SaveTo.Text,System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.Read);
43 CompressionHelper.DeCompress(CompressionHelper.CompressionMode.GZip , targetstream, saveStream);
44 targetstream.Close();
45 saveStream.Close();
46 }
1public static class CompressionHelper
2 {
3 public enum CompressionMode
4 {
5 GZip = 0 ,
6 Deflate = 1
7 }
8 public static void Compress(CompressionMode compression, Stream orgStream, Stream cmpStream)
9 {
10 switch( compression )
11 {
12 case CompressionMode.GZip:
13 (new GZipCompression()).Compress(orgStream, cmpStream); break;
14 case CompressionMode.Deflate:
15 (new DeflateCompression()).Compress(orgStream, cmpStream); break;
16 }
17 }
18 public static void DeCompress(CompressionMode compression, Stream cmpStream, Stream orgStream)
19 {
20 switch( compression )
21 {
22 case CompressionMode.GZip:
23 (new GZipCompression()).DeCompress(cmpStream, orgStream);break;
24 case CompressionMode.Deflate:
25 (new DeflateCompression()).DeCompress(cmpStream, orgStream);break;
26 }
27 }
28 }
完整的代码附件:/Files/qin0773/Gzip.zip
====================================================================
参考了 http://www.cnblogs.com/dajianshi/archive/2008/03/18/1111180.html 的文章的巴山在回复中提到
“发现GZipStream的Close方法,会调用Dispose方法,直到调FastEncoder.Finish方法,而这方法,里面就一个有微软调试语句说:“only call this when we have no more data to compress!”,对了,就是因为这个方法,给压缩流提供了结束标志,所以在读数据前,必须告诉GZipStream我数据压完了”
然后仔细检查Compress方法 传入基础流,然后包装成zipStream,调用后在Compress的外部对基础流调用了Close,但是没有对包装的GzipStream调用Close方法。赶忙加上。问题解决!修改后的代码如下:
1 public void Compress(System.IO.Stream orgStream, System.IO.Stream cmpStream)
2 {
3 System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(cmpStream, System.IO.Compression.CompressionMode.Compress);
4 BinaryWriter writer = new BinaryWriter(zipStream);
5 BinaryReader reader = new BinaryReader(orgStream);
6 while (true)
7 {
8 byte[] buffer = reader.ReadBytes(1024);
9 if (buffer == null || buffer.Length < 1)
10 break;
11 writer.Write(buffer);
12 }
13 writer.Close();
14 }
1 public void DeCompress(System.IO.Stream cmpStream, System.IO.Stream orgStream)
2 {
3 System.IO.Compression.GZipStream zipStream = new System.IO.Compression.GZipStream(cmpStream, System.IO.Compression.CompressionMode.Decompress);
4 BinaryReader reader = new BinaryReader(zipStream);
5 BinaryWriter writer = new BinaryWriter(orgStream);
6 while (true)
7 {
8 byte[] buffer = reader.ReadBytes(1024);
9 if (buffer == null || buffer.Length < 1)
10 break;
11 writer.Write(buffer);
12 }
13 writer.Close();
14 }
问题是解决了~ 可是对这个Close方法任有点梗怀。也不应在流关闭后再调用它的Read方法(这里请参见http://www.cnblogs.com/dajianshi/archive/2008/03/18/1111180.html )应该由一个更好的方法显式的调用来声明压缩完成。