.net中使用GZipStream进行Gzip压缩的问题

如下两个方法~ 一个压缩,一个解压缩。 都是直接调用 System.IO.Compression.GZipStream 类。

压缩正常,可是解压缩的方法确莫名奇妙的出错。

ContractedBlock.gif ExpandedBlockStart.gif Compress
 1public void Compress(System.IO.Stream orgStream, System.IO.Stream cmpStream)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 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)
 8ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 9                int bytesRead = orgStream.Read(buffer, offset, 100);
10                if (bytesRead == 0)
11ExpandedSubBlockStart.gifContractedSubBlock.gif                {
12                    break;
13                }

14                zipStream.Write(buffer, 0, bytesRead);
15            }

16        }

 

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 1        public void DeCompress(System.IO.Stream cmpStream, System.IO.Stream orgStream)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 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)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif            {   //cmpStream明明有数据,但是这里个bytesRead第一次循环有时会为0,造成解压缩失败,有时又可以。怎么回事?????
 8                int bytesRead = zipStream.Read(buffer, offset, 100);
 9                if (bytesRead == 0)
10ExpandedSubBlockStart.gifContractedSubBlock.gif                {
11                    break;
12                }

13                orgStream.Write(buffer, 0, bytesRead);
14            }

15        }

 

不知道是不是System.IO.Compression.GZipStream的使用方法不对,求助园子里的朋友.

====================================================

补充一下修改后的完整代码,这个问题还是没解决,怀疑是GzipStream本身有Bug,发布出来希望有同样遇到问题的朋友能提点一下~

 

 1  // 压缩
 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          }

 

 

ContractedBlock.gif ExpandedBlockStart.gif CompressionHelper
 1public static class CompressionHelper
 2ExpandedBlockStart.gifContractedBlock.gif    {
 3        public enum CompressionMode
 4ExpandedSubBlockStart.gifContractedSubBlock.gif        
 5            GZip = 0 ,
 6            Deflate = 1
 7        }

 8        public static void Compress(CompressionMode compression, Stream orgStream, Stream cmpStream)
 9ExpandedSubBlockStart.gifContractedSubBlock.gif        {
10            switch( compression )
11ExpandedSubBlockStart.gifContractedSubBlock.gif            {
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)
19ExpandedSubBlockStart.gifContractedSubBlock.gif        {
20            switch( compression )
21ExpandedSubBlockStart.gifContractedSubBlock.gif            {
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方法。赶忙加上。问题解决!修改后的代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Compress
 1        public void Compress(System.IO.Stream orgStream, System.IO.Stream cmpStream)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 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)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 8                byte[] buffer = reader.ReadBytes(1024);
 9                if (buffer == null || buffer.Length < 1)
10                    break;
11                writer.Write(buffer);
12            }

13            writer.Close();
14        }

 

ContractedBlock.gif ExpandedBlockStart.gif DeCompress
 1        public void DeCompress(System.IO.Stream cmpStream, System.IO.Stream orgStream)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 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)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 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 )应该由一个更好的方法显式的调用来声明压缩完成。

 

转载于:https://www.cnblogs.com/qin0773/archive/2009/06/09/1499864.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值