【问题标题】:GZipStream and DeflateStream produce bigger filesGZipStream 和 DeflateStream 产生更大的文件
【发布时间】:2010-10-05 13:27:37
【问题描述】:

我正在尝试在 C# 中使用 deflate/gzip 流,但压缩后的文件似乎比以前大。

例如,我压缩了一个 900ko 的 docx 文件,但它产生了一个 1.4Mo 的文件!

它对我尝试的每个文件都执行此操作。

我做这件事的方式可能是错的吗?这是我的代码:

  FileStream input = File.OpenRead(Environment.CurrentDirectory + "/file.docx");
  FileStream output = File.OpenWrite(Environment.CurrentDirectory + "/compressedfile.dat");

  GZipStream comp = new GZipStream(output, CompressionMode.Compress);

  while (input.Position != input.Length)
      comp.WriteByte((byte)input.ReadByte());

  input.Close();

  comp.Close(); // automatically call flush at closing
  output.Close();

【问题讨论】:

  • 您确实意识到将任意输入压缩至少一个字节的压缩方法不存在?因此,特别是如果您正在尝试压缩已经接近随机的数据,例如预压缩数据,您可能会看到大小增加。
  • .docx 已使用 ZIP 压缩进行压缩(尝试重命名为 .zip 并进行探索)。如果第二级压缩会产生任何好处,我会感到惊讶。
  • 它应该只在刷新时有效地进行压缩,所以它不应该改变任何东西
  • @spender > 不知道,我会尝试使用其他文件格式
  • 您是否尝试过压缩 .txt 文件?

标签: c# gzipstream deflatestream


【解决方案1】:

这么大的区别对我来说似乎很奇怪,但你应该记住docx本身是用ZIP压缩的,所以没有理由再次压缩,结果通常会更大。

【讨论】:

  • 是的,谢谢,我不知道,这就是为什么它不起作用:) 尝试使用 .txt 和其他格式,它似乎更好。但它仍然不适用于自制的序列化文件类型......但最后没关系,只是想看看如何使用这些压缩流:)
【解决方案2】:

首先,与 zip、7z 等相比,deflate/gzip 流在压缩方面非常糟糕。

其次,docx(以及所有末尾带有“x”的 MS 文档格式)无论如何都只是 .zip 文件。将 .docx 重命名为 .zip 以显示烟雾和镜子。

因此,当您在 docx 上运行 deflate/gzip 时,它实际上会使文件变大。 (这就像对高压缩率的压缩文件进行低压缩率的压缩。)

但是,如果您在 HTML 或文本文件或未压缩的文件上运行 deflate/gzip,那么它实际上会做得很好。

【讨论】:

  • 是的,谢谢,正如其他评论中所说,不知道 docx 已经被压缩。当然 7z 和其他库更好,但只是想尝试一下,看看他们能做什么
  • 这似乎是一个完全无效的评论:与 zip、7z 等相比,deflate/gzip 流在压缩方面非常糟糕。事实上,99% 的 zip 文件使用 DEFLATE 作为压缩格式。所以 zip 可能不比 DEFLATE 好,因为它用元数据扩充了压缩流。
  • DeflateStream 实际上增加先前压缩数据的大小的现象是 2006 年与 Microsoft 一起公开的一个错误的主题:connect.microsoft.com/VisualStudio/feedback/details/93930/…
【解决方案3】:

尽管正如其他人所指出的那样,您指定的示例文件确实已经压缩 - 最大的问题是要了解,与大多数压缩实用程序不同,DeflateStreamGZipStream 类只是尝试标记/压缩数据流,而没有智能,即所有额外的标记(开销)实际上都在增加所需的数据量。 Zip、7z 等足够聪明,可以知道如果数据很大程度上是随机熵(实际上是不可压缩的),它们只会“按原样”存储数据(存储,而不是压缩),而不是尝试进一步压缩。

【讨论】:

  • 这不是真的:Zip、7z 等足够聪明,可以知道如果数据很大程度上是随机熵(实际上是不可压缩的),它们只是“按原样”存储数据(存储,未压缩),而不是尝试进一步压缩它。 ZIP 只是一种文件格式。它什么都不“知道”。生成 ZIP 文件的程序可能会执行您描述的操作,但 ZIP 格式不会。
  • DeflateStream 实际上膨胀之前压缩数据大小的现象是微软已公开的一个bug的主题:connect.microsoft.com/VisualStudio/feedback/details/93930/…
  • 不是在谈论格式(很遗憾)。正在谈论以相应格式写入数据的压缩实用程序。
【解决方案4】:

我在压缩包含 jpg 数据的数据库时遇到了同样的问题。我尝试了dotnetzip - 替换掉并获得了不错的压缩(也支持 Compact Framework!):

MS : 10MB -> 10.0MB
DNZ: 10MB ->  7.6MB

【讨论】:

    【解决方案5】:

    我不认为 GzipStream 和 DeflateStream 旨在压缩文件。使用像 SharpZipLib 这样的文件压缩器可能会更好。

    【讨论】:

    • 它们用于压缩和解压缩。我目前正在阅读 MCTS 70-536 认证书,它们在那里被使用 ^^
    • 它们是干什么用的? msdn.microsoft.com/en-us/library/… "GZipStream 类提供用于压缩和解压缩流的方法和属性。"
    • 它们非常擅长压缩文件,并且在许多情况下比 zip 更方便,因为它们直接处理文件而不是创建存档,并且您可以直接从网络服务器输出它们而不是在每次都飞。将 .gz 附加到名称(在原始扩展名之后而不是替换它)对于 gzip 文件很常见。并不是说 SharpZipLib 在很多情况下都不是更好。
    • @Dave Swersky:这是一个相当大胆的声明。可以使用霍夫曼编码来压缩文件,然后将其压缩以使其更小。根据您的第一个压缩技术有多糟糕,第二个压缩技术可能会使它变得更好或更糟。
    • @Excel:我的立场是正确的。我想结合两种不同类型的压缩可以提高总体比率,但我会说使用 ZIP 两次是行不通的。
    猜你喜欢
    • 2011-02-05
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多