2011-09-21 38 views
2

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

+0

对不起有任何困惑,但答案都集中在我冗长的帖子的错误部分。潜在问题“压缩流算法是否检测到数据未被压缩并按原样传递?”。看起来大多数答案都是“否”,但从规范:(1)从输入流中读取块标题。 (2)如果没有压缩存储,则跳过当前部分处理的字节中的任何剩余位(3)复制LEN字节的数据以输出。所以我认为答案是YES – plyawn

+0

并且为了进一步澄清这是** Decompress **操作 – plyawn

+0

我的回答仍然是正确的。在尝试解压缩未压缩的数据时,DeflateStream类没有任何优雅的功能。 – Cheeso

回答

2

不,在DeflateStream中没有这样的魔法。

内置的deflateStream表现出一个压缩异常,其中之前压缩的数据实际上增加了大小。之前已向微软报告过这种情况,但他们拒绝解决这个问题。它必须在DEFLATE协议的DeflateStream中实现一个天真的实现。 方法,我知道的避免这些问题:

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

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

如果您选择前一种情况,您仍然有压缩已经压缩的东西的情况。换句话说,不必要的双重压缩。所以你可能想要考虑避免这种情况,不管你选择什么。

0

这一切都取决于如何创建DEFLATE流。

DEFLATE支持“非压缩块”(BTYPE = 00),并且该块中的所有数据(如果使用)都是逐字压缩存储的,而不是压缩 - 只是块头,长度和原始数据。但是,流可以是有效的DEFLATE流,并且包含零(或不足)的“非压缩”块,即使这导致了低于标准压缩比。

整体压缩比将取决于数据,压缩器算法/实现以及它在执行压缩时付出的努力量。

快乐编码。

0

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

通过将数据划分为块,决定每个块如何表示数据,并在每块的开始处包括一个标题以标识其存储方式,可以稍微缓解这种影响。不幸的是,额外的块头将增加到结果流的大小。此外,许多压缩方案在处理流时提高了效率;即使压缩整个文件将导致相当大的空间节省(因为压缩器可以例如建立普通字节序列的字典),文件中的每个1k块可能会单独展开,如果单独“压缩”的话。可以设计一个压缩/解压缩对,这样扩展的数据块将被压缩器逐字写出(头部字节指示它是什么),并且具有以相同方式阻塞的非压缩器处理压缩器可能已经完成了,以便向字典中添加将该块以“压缩”形式存储的相同的字节序列。这样的方法可能是一个很好的方法,但它会增加非编码器的复杂性。

我怀疑DeflateStream的最大问题是,如果不生成与现有“解压缩”代码不兼容的压缩数据,可能无法改善最坏情况下的“压缩”性能。假设有一个字节为Q的字符串,并且需要一个字节序列,当它被提供给.net 2.0附带的“解压缩”代码时,将产生相同的序列。很可能,对于Q的一些可能的值,没有这样的输入序列不会比Q大很多。如果是这样的话,微软不可能在没有时间机器的情况下“修复”问题。