.NET GZipStream 压缩和解压缩

发布于 2024-08-07 18:50:11 字数 1094 浏览 6 评论 0原文

下面这段代码有什么问题。我总是得到 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;
        }

如果您能指出我在哪里犯了错误,我将不胜感激。

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()
        {
            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;
        }

I will really appreciate if you can point out where I am making a mistake.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凑诗 2024-08-14 18:50:11

Write 调用后关闭 GZipStream

如果不调用Close,某些数据可能会被缓冲但尚未写入底层流。

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.

逆光飞翔i 2024-08-14 18:50:11

试试这个代码:

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 来获取样本数据的字符串。

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

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

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;
        }
一身仙ぐ女味 2024-08-14 18:50:11

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

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

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

这是最终的代码:-

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 对象进行压缩/解压缩工作时遇到了很大的麻烦。最后,我认为我以正确的方式得到了它。非常感谢大家,因为解决方案来自你们所有人。

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.

薆情海 2024-08-14 18:50:11

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


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

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);
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文