简体   繁体   English

使用 GZipStream 对 MemoryStream 进行编程压缩/解压缩

[英]Programmatic compression/decompression to MemoryStream with GZipStream

I built (based on a CodeProject article) a wrapper class (C#) to use a GZipStream to compress a MemoryStream .我(基于 CodeProject 文章)构建了一个包装器 class (C#) 以使用GZipStream压缩MemoryStream It compresses fine but doesn't decompress.它压缩得很好,但不解压缩。 I've looked at many other examples that have the same problem, and I feel like I'm following what's said but still am getting nothing when I decompress.我查看了许多其他具有相同问题的示例,我觉得我正在遵循所说的内容,但在解压缩时仍然一无所获。 Here's the compression and decompression methods:以下是压缩和解压方法:

public static byte[] Compress(byte[] bSource)
{

    using (MemoryStream ms = new MemoryStream())
    {
        using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true))
        {
            gzip.Write(bSource, 0, bSource.Length);
            gzip.Close();
        }

        return ms.ToArray();
    }
}


public static byte[] Decompress(byte[] bSource)
{

    try
    {
        using (MemoryStream ms = new MemoryStream())
        {
            using (GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress, true))
            {
                gzip.Read(bSource, 0, bSource.Length);
                gzip.Close();
            }

            return ms.ToArray();
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Error decompressing byte array", ex);
    }
}

Here's an example of how I use it:这是我如何使用它的示例:

string sCompressed = Convert.ToBase64String(CompressionHelper.Compress("Some Text"));
// Other Processes
byte[] bReturned = CompressionHelper.Decompress(Convert.FromBase64String(sCompressed));
// bReturned has no elements after this line is executed

There is a bug in Decompress method.解压方法有一个错误。

The code does not read content of bSource .该代码不读取bSource的内容。 On the contrary, it overrides its content wile reading from empty gzip, created based on empty memory stream.相反,它会覆盖从空 gzip 读取的内容,该 gzip 基于空 memory stream 创建。

Basically what your version of code is doing:基本上你的代码版本在做什么:

//create empty memory
using (MemoryStream ms = new MemoryStream())

//create gzip stream over empty memory stream
using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress, true))

// write from empty stream to bSource
gzip.Write(bSource, 0, bSource.Length);

The fix could look like this:修复可能如下所示:

public static byte[] Decompress(byte[] bSource)
{
    using (var inStream = new MemoryStream(bSource))
    using (var gzip = new GZipStream(inStream, CompressionMode.Decompress))
    using (var outStream = new MemoryStream())
    {
        gzip.CopyTo(outStream);
        return outStream.ToArray();
    }
}

The OP said in an edit, now rolled back: OP 在编辑中说,现在回滚:

Thanks to Alex's explanation of what was going wrong, I was able to fix the Decompress method.感谢 Alex 对问题所在的解释,我能够修复 Decompress 方法。 Unfortunately, I'm using.Net 3.5, so I wasn't able to implement the Stream.CopyTo method he suggested.不幸的是,我使用的是.Net 3.5,所以我无法实现他建议的 Stream.CopyTo 方法。 With his explanation, though, I was able to figure out a solution.不过,在他的解释下,我找到了解决办法。 I made the appropriate changes to the Decompress method below.我对下面的 Decompress 方法进行了适当的更改。

    public static byte[] Decompress(byte[] bSource)
    {
        try
        {
            using (var instream = new MemoryStream(bSource))
            {
                using (var gzip = new GZipStream(instream, CompressionMode.Decompress))
                {
                    using (var outstream = new MemoryStream())
                    {
                        byte[] buffer = new byte[4096];

                        while (true)
                        {
                            int delta = gzip.Read(buffer, 0, buffer.Length);

                            if (delta > 0)
                                outstream.Write(buffer, 0, delta);

                            if (delta < 4096)
                                break;
                        }
                        return outstream.ToArray();
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error decompressing byte array", ex);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM