.NET GZipStream压缩和解压缩

时间:2009-10-19 20:14:24

标签: .net compression gzipstream

以下代码有什么问题。我总是得到FALSE,这意味着在压缩之后,解压缩的数据与原始值不匹配。

public static bool Test()
        {
            string sample = "This is a compression test of microsoft .net gzip compression method and decompression methods";
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            byte[] data = encoding.GetBytes(sample);
            bool result = false;

            //Compress
            MemoryStream cmpStream;
            cmpStream = new MemoryStream();
            GZipStream hgs = new GZipStream(cmpStream, CompressionMode.Compress);
            hgs.Write(data, 0, data.Length);
            byte[] cmpData = cmpStream.ToArray();

            MemoryStream decomStream;
            decomStream = new MemoryStream(cmpData);
            hgs = new GZipStream(decomStream, CompressionMode.Decompress);
            hgs.Read(data, 0, data.Length);

            string sampleOut = System.BitConverter.ToString(data);

            result = String.Equals(sample, sampleOut) ;
            return result;
        }

如果你能指出我犯错误的地方,我将非常感激。

4 个答案:

答案 0 :(得分:19)

GZipStream来电后关闭Write

在不调用Close的情况下,某些数据可能会被缓冲,并且尚未写入基础流。

答案 1 :(得分:14)

试试这段代码:

public static bool Test()
        {
            string sample = "This is a compression test of microsoft .net gzip compression method and decompression methods";

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

            byte[] data = encoding.GetBytes(sample);
            bool result = false;

            // Compress
            MemoryStream cmpStream = new MemoryStream();

            GZipStream hgs = new GZipStream(cmpStream, CompressionMode.Compress);

            hgs.Write(data, 0, data.Length);

            byte[] cmpData = cmpStream.ToArray();

            MemoryStream decomStream = new MemoryStream(cmpData);

            hgs = new GZipStream(decomStream, CompressionMode.Decompress);
            hgs.Read(data, 0, data.Length);

            string sampleOut = encoding.GetString(data);

            result = String.Equals(sample, sampleOut);
            return result;
        }

问题是你没有使用ASCIIEncoder来获取sampleData的字符串。

编辑:这是一个清理版本的代码,以帮助完成关闭/处置:

public static bool Test()
        {
            string sample = "This is a compression test of microsoft .net gzip compression method and decompression methods";

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

            byte[] data = encoding.GetBytes(sample);

            // Compress.
            GZipStream hgs;
            byte[] cmpData;

            using(MemoryStream cmpStream = new MemoryStream())
            using(hgs = new GZipStream(cmpStream, CompressionMode.Compress))
            {
                hgs.Write(data, 0, data.Length);
                hgs.Close()

                // Do this AFTER the stream is closed which sounds counter intuitive 
                // but if you do it before the stream will not be flushed
                // (even if you call flush which has a null implementation).
                cmpData = cmpStream.ToArray();
            }  

            using(MemoryStream decomStream = new MemoryStream(cmpData))
            using(hgs = new GZipStream(decomStream, CompressionMode.Decompress))
            {
                hgs.Read(data, 0, data.Length);
            }

            string sampleOut = encoding.GetString(data);

            bool result = String.Equals(sample, sampleOut);
            return result;
        }

答案 2 :(得分:9)

解决问题有三个问题。 1. WRITE GZipStream需要关闭后:: hgs.Close();

  1. GZipStream读取需要使用WHILE循环并将未压缩数据的较小缓冲区写入MemoryStream :: outStream.Write(...);

  2. 转换解压缩的byte []数组需要使用编码转换:: string sampleOut = encoding.GetString(data);

  3. 以下是最终代码: -

    public static bool Test()
            {
                string sample = "This is a compression test of microsoft .net gzip compression method and decompression methods";
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
                byte[] data = encoding.GetBytes(sample);
                bool result = false;
    
                // Compress 
                MemoryStream cmpStream = new MemoryStream();
                GZipStream hgs = new GZipStream(cmpStream, CompressionMode.Compress, true);
    
                hgs.Write(data, 0, data.Length);
                hgs.Close();
    
    
                //DeCompress
                byte[] cmpData = cmpStream.ToArray();
                MemoryStream decomStream = new MemoryStream(cmpData);
    
                data = new byte[data.Length];
                hgs = new GZipStream(decomStream, CompressionMode.Decompress, true);
    
                byte[] step = new byte[16]; //Instead of 16 can put any 2^x
                MemoryStream outStream = new MemoryStream();
                int readCount;
    
                do
                {
                    readCount = hgs.Read(step, 0, step.Length);
                    outStream.Write(step, 0, readCount);
                } while (readCount > 0);
                hgs.Close();
    
                string sampleOut = encoding.GetString(outStream.ToArray());
                result = String.Equals(sample, sampleOut);
                return result; 
            }
    

    使用Microsoft .NET GZipStream对象进行压缩/解压缩工作真的很麻烦。最后,我想我是以正确的方式得到它的。非常感谢所有人,因为解决方案来自你们所有人。

答案 3 :(得分:3)

这是我最终解决方案的清理版本:


  [Test]
  public void Test_zipping_with_memorystream()
  {
   const string sample = "This is a compression test of microsoft .net gzip compression method and decompression methods";
   var encoding = new ASCIIEncoding();
   var data = encoding.GetBytes(sample);
   string sampleOut;
   byte[] cmpData;

   // Compress 
   using (var cmpStream = new MemoryStream())
   {
    using (var hgs = new GZipStream(cmpStream, CompressionMode.Compress))
    {
     hgs.Write(data, 0, data.Length);
    }
    cmpData = cmpStream.ToArray();
   }

   using (var decomStream = new MemoryStream(cmpData))
   {
    using (var hgs = new GZipStream(decomStream, CompressionMode.Decompress))
    {
     using (var reader = new StreamReader(hgs))
     {
      sampleOut = reader.ReadToEnd();
     }
    }
   }

   Assert.IsNotNullOrEmpty(sampleOut);
   Assert.AreEqual(sample, sampleOut);
  }
相关问题