使用GZipStream对MemoryStream进行编解码压缩

4

我基于一个CodeProject文章编写了一个包装器类(C#),使用压缩。它可以很好地压缩,但无法解压缩。我查看了许多其他有相同问题的示例,感觉我在遵循所说的方法,但在解压缩时仍然得不到任何东西。这是压缩和解压缩方法:

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

以下是我使用它的示例:
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
2个回答

6

解压方法中存在一个bug。

该代码没有读取bSource的内容。相反,在从空内存流创建的空gzip文件中读取时,它会覆盖其内容。

基本上,您的代码版本正在执行以下操作:

//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);

修复方案可能如下所示:
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();
    }
}

1

楼主在编辑中提到,现已撤回:

感谢Alex对于问题的解释,我成功修复了Decompress方法。不幸的是,我使用的是.Net 3.5版本,无法实现他建议的Stream.CopyTo方法。但通过他的解释,我找到了一种解决方案。我在下面的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);
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接