c# - 原始文件比 GZip 解压文件大

标签 c# .net gzip compression

所以我试图压缩一个字节数组(通过流)。 ExtendedStream 只是我创建的一个与基本流(默认为 MemoryStream)接口(interface)的类。如果我获取原始数据,压缩它,解压缩它,然后将解压缩数据的大小与原始数据的大小(压缩前)进行比较,结果发现它比原始数据小。

原始长度:51695,压缩长度:26014,解压长度:48685。

我正在存储图 block (7 个字节)。使用 System.IO.Compression 命名空间中提供的 GZip 类进行压缩。

    public static ExtendedStream GZipDecompress(ExtendedStream stream)
    {
        ExtendedStream outStream = new ExtendedStream();
        GZipStream decompressStream = new GZipStream(stream.BaseStream, CompressionMode.Decompress, true);
        int b = -1;

        while ((b = decompressStream.ReadByte()) != -1)
        {
            outStream.WriteByte((Byte)b);
        }

        outStream.Seek(0, SeekOrigin.Begin);
        return outStream;
    }

    public static ExtendedStream GZipCompress(ExtendedStream stream)
    {
        ExtendedStream outStream = new ExtendedStream(); // base stream is a memorystream
        GZipStream compressStream = new GZipStream(outStream.BaseStream, CompressionMode.Compress, true);
        compressStream.Write(stream.ToArray(), 0, (int)stream.Length);
        compressStream.Flush();
        outStream.Seek(0, SeekOrigin.Begin);
        return outStream;
    }

希望这是足够的信息。

最佳答案

必须关闭压缩流;由于 block 问题,在您执行之前它无法写入所有数据:

public static ExtendedStream GZipCompress(ExtendedStream stream)
{
    ExtendedStream outStream = new ExtendedStream();
    using(var compressStream = new GZipStream(outStream.BaseStream, CompressionMode.Compress, false)) {
        compressStream.Write(stream.GetBuffer(), 0, (int)stream.Length);
    }
    outStream.Seek(0, SeekOrigin.Begin);
    return outStream;
}

注意:通常我会使用 CopyTo(或手动循环)来进行写入,但由于这是基于内存的 GetBuffer() 更便宜。

您的减压可以很简单:

decompressStream.WriteTo(outStream);

通过这两个部分,最大的问题(困扰你的问题)是不处理你的一次性元素。您必须这样做;这是 API 的要求。为了避免过早处置外部流,请将“false”传递给 GZipStream 构造函数。例如:

using(var decompressStream = new GZipStream(stream.BaseStream, CompressionMode.Decompress, false)) {
    decompressionStream.CopyTo(outStream);
}

关于c# - 原始文件比 GZip 解压文件大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9434626/

相关文章:

c# - 如果当前副本正在使用中,则打开文件的卷影副本

C# 结构数组和赋值性能

.net - 注册为在客户端计算机上注册的 Excel 编写的 COM 服务器时出现问题(无法设置 mscoree.dll 的完整路径)

c# - 异常处理的良好实践设计模式

Perl 只读取特定的 gz 文件行

c# - 通过 C# MVC 从 Amazon S3 检索图像

c# - 我可以获得对象的通用类型吗?

c# - “您必须添加对 Microsoft.Practices.EnterpriseLibrary.Common 的引用”,即使程序集位于 GAC 中

javascript - GZip 完整的 ASP.NET 网站

html - 浏览器是否以压缩形式缓存 gzipped html?