我不熟悉DeflateStream的内部结构,但是我需要将文件存储在供应商的数据库系统中,该系统在二进制附件上使用DeflateStream。我注意到的第一件事是我的所有文件在压缩后都是10-50%BIGGER,但我将其归因于已经高度压缩的文件(在这种情况下它们都是PDF)的不太复杂的压缩算法。然而,我的问题涉及到这样一个事实:当我将原始文件写入BLOB时,供应商的应用程序打开它没有任何问题(它打开了我使用deflate压缩的附件)。压缩数据上是否有一个标题告诉DeflateStream数据是否未压缩并且基本上按原样传递? This是规范;任何熟悉它的人都可以指出这个定义的地方 - 或者我是不是基地而且供应商在幕后做了一些魔术?
答案 0 :(得分:2)
不,DeflateStream中没有这样的魔力。
内置的deflateStream表现出压缩异常,其中先前压缩的数据实际上增加了大小。此前已向Microsoft报告,但他们拒绝解决此问题。它与DEFLATE协议的DeflateStream中的天真实现有关。 我知道的方法是避免这个问题:
使用不会出现此问题的替代deflateStream。有关示例,请参阅DotNetZip。 它包含一个可以正常工作的DeflateStream。
使用损坏的DeflateStream,压缩流,比较大小,如果“压缩”流更大,则回退到使用“未压缩”流。
如果选择前一种情况,您仍然具有压缩已经压缩的内容的条件。换句话说,不必要的双重压缩。所以无论你选择什么,你都可以考虑避免这种情况。
答案 1 :(得分:0)
这一切都取决于如何创建DEFLATE流。
DEFLATE支持“非压缩块”(BTYPE = 00),如果使用该块中的所有数据,则逐字存储而不压缩 - 只是块头,长度和原始块数据。但是,流可以是有效的DEFLATE流,并且包含零(或不够)“非压缩”块,即使这会导致低于压缩比率。
整体压缩率取决于数据,压缩器算法/实现以及它在执行压缩时所付出的努力程度。
快乐的编码。
答案 2 :(得分:0)
流压缩与文件压缩不同。压缩文件时,通常可以对整个文件进行多次传递,并确定在必须提交之前使用哪种压缩方案。压缩流时,通常需要在压缩例程处理足够的数据之前开始输出数据,以了解哪种压缩方法最佳。
通过将数据划分为块,确定每个块如何表示数据,并在每个块的开头包括标识其如何存储的标题,可以在某种程度上减轻这种影响。不幸的是,额外的块头将增加生成的流的大小。此外,许多压缩方案在处理流时提高了效率;如果压缩整个文件将导致相当大的空间节省(因为压缩器可以例如构建公共字节序列的字典),所以很可能文件中的每个1k块在单独“压缩”时会扩展。可以设计一个压缩/解压缩对,这样一个可以扩展的数据块将由压缩器逐字写出(带有一个标题字节表示它是什么),并且具有阻塞相同方式的uncompresser进程如果压缩器以“压缩”形式存储,那么压缩器可以完成,以便向字典中添加相同的字节序列。这样的方法可能是一个很好的方法,但它会大大增加uncompresser的复杂性。
我怀疑DeflateStream最大的问题是,如果不生成与现有“uncompress”代码不兼容的压缩数据,可能无法改善最坏情况下的“压缩”性能。假设有一个字节串Q,并且需要一个字节序列,当输入到.net 2.0附带的“解压缩”代码时,它将产生相同的序列。很可能对于Q的某些可能值,没有这样的输入序列并不比Q大很多。如果是这样的话,微软就没有办法在没有时间机器的情况下“解决”问题。