【问题标题】:Does DeflateStream "skip" decompression if the data was not originally compressed?如果数据最初没有被压缩,DeflateStream 会“跳过”解压缩吗?
【发布时间】:2011-09-21 16:06:38
【问题描述】:

我不熟悉 DeflateStream 的内部结构,但我需要将文件存储在供应商的数据库系统中,该系统在二进制附件上使用 DeflateStream。我注意到的第一件事是我的所有文件在压缩后都大了 10-50%,但我将其归因于已经高度压缩的文件(在这种情况下它们都是 PDF)之上的不太复杂的压缩算法。然而,我的问题涉及这样一个事实,即当我刚刚将原始文件写入 BLOB 时,供应商的应用程序打开它没有问题(它也打开了我用 deflate 压缩的附件)。压缩数据上是否有一个标头告诉 DeflateStream 数据未压缩并且基本上按原样传递? This 是规范;任何熟悉它的人都可以指出这是在哪里定义的 - 还是我不在基地并且供应商在幕后做了一些魔术?

【问题讨论】:

  • 抱歉有任何混淆,但答案集中在我冗长帖子的错误部分。基本问题“放气流算法是否检测到数据未压缩并按原样传递?”。似乎大多数答案都说“不”,但从规范来看:(1)从输入流中读取块头。 (2) 如果未压缩存储,则跳过当前部分处理的字节中的任何剩余位 (3) 复制 LEN 字节的数据到输出。所以我认为答案是肯定的
  • 并进一步澄清这是在 Decompress 操作
  • 我的回答还是正确的。 DeflateStream 类中没有什么魔法可以在尝试解压缩未压缩数据时优雅地不执行任何操作。

标签: c# rfc deflatestream


【解决方案1】:

不,DeflateStream 中没有这样的魔力。

内置的 deflateStream 表现出压缩异常,其中先前压缩的数据实际上会增加大小。之前已向 Microsoft 报告过此问题,但他们拒绝解决此问题。它与 DEFLATE 协议的 DeflateStream 中的幼稚实现有关。 我知道的避免该问题的方法:

  • 使用不会出现此问题的替代 deflateStream。参见 DotNetZip 示例。 它包括一个可以正常工作的 DeflateStream。

  • 使用损坏的 DeflateStream,压缩流,比较大小,如果“压缩”流较大,则回退到使用“未压缩”流。

如果你选择前一种情况,你仍然有压缩已经压缩的东西的情况。换句话说,不必要的双重压缩。因此,无论您选择什么,您都可能希望避免这种情况。

【讨论】:

    【解决方案2】:

    流压缩不同于文件压缩。压缩文件时,通常可以对整个文件进行多次传递,并在必须提交之前确定使用哪种压缩方案。压缩流时,通常需要在压缩例程处理足够的数据以了解哪种压缩方法最佳之前开始输出数据。

    通过将数据划分为块、为每个块决定如何表示数据以及在每个块的开头包含一个标头来标识数据的存储方式,可以在一定程度上减轻这种影响。不幸的是,额外的块头会增加结果流的大小。此外,许多压缩方案在处理流时提高了效率。如果单独“压缩”,文件中的每 1k 块很可能会扩展,即使压缩整个文件会节省大量空间(因为压缩器可以例如建立一个公共字节序列的字典)。可以设计一个压缩/解压缩对,以便压缩器逐字写出一个会扩展的数据块(带有一个标头字节表明它是什么),并让解压缩器进程以相同的方式阻塞压缩器可以这样做,以便将块以“压缩”形式存储时添加的相同字节序列添加到字典中。这种方法可能是一个不错的方法,尽管它会大大增加解压缩器的复杂性。

    不过,我怀疑 DeflateStream 的最大问题是,在不产生与现有“解压缩”代码不兼容的压缩数据的情况下,可能没有任何方法可以提高最坏情况下的“压缩”性能。假设有一个字节串 Q,并且需要一个字节序列,当将其馈送到 .net 2.0 附带的“解压缩”代码时,将产生相同的序列。很可能对于某些可能的 Q 值,没有这样的输入序列不会比 Q 大很多。如果是这样的话,没有时间机器,微软就无法“解决”这个问题。

    【讨论】:

      【解决方案3】:

      这完全取决于 DEFLATE 流的创建方式。

      DEFLATE 支持“非压缩块”(BTYPE=00),并且该块中的所有数据(如果被使用)将逐字存储,不进行压缩——只有块头、长度和原始数据。然而,一个流可以是一个有效的 DEFLATE 流并且包含零个(或不够)“非压缩”块,即使这会导致低于标准的压缩率。

      整体压缩率取决于数据、压缩器算法/实现以及执行压缩所付出的努力。

      编码愉快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        • 2010-11-02
        相关资源
        最近更新 更多