.NET GZipStream compress and decompress

前端 未结 4 1817
无人及你
无人及你 2020-12-08 22:55

What is wrong with this code below. I always get FALSE, meaning after compression, decompressed data does not match original value.

public static bool Test()         


        
相关标签:
4条回答
  • 2020-12-08 23:05

    Close the GZipStream after the Write call.

    Without calling Close, there's a possibility that some data is buffered and is not written to the underlying stream yet.

    0 讨论(0)
  • 2020-12-08 23:07

    Here's my cleaned up version of the final solution:

    
      [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);
      }
    
    0 讨论(0)
  • 2020-12-08 23:10

    Try this code:

    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;
            }
    

    The problem what that you were not using the ASCIIEncoder to get the string back for sampleData.

    EDIT: Here's a cleaned up version of the code to help with Closing/Disposing:

    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;
            }
    
    0 讨论(0)
  • 2020-12-08 23:11

    There were three issues to solve the problem. 1. After WRITE GZipStream NEEDED to be closed :: hgs.Close();

    1. GZipStream read needed to be used a WHILE loop and writing the smaller buffer of uncompressed data to a MemoryStream :: outStream.Write( ... );

    2. The converting of decompressed byte[] array needed to use encoding conversion :: string sampleOut = encoding.GetString(data);

    Here is the final code:-

    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; 
            }
    

    I had really trouble to get compress/decompress work with Microsoft .NET GZipStream object. Finally, I think I got it in right way. many thanks to all as the solution came from all of you.

    0 讨论(0)
提交回复
热议问题