由GZIP压缩的文件增长而不是缩小

时间:2009-01-26 13:56:33

标签: vb.net gzip

我使用下面的代码来压缩文件,它们不断增长而不是缩小。我压缩了一个4 kb的文件,它变成了6.由于压缩开销,这对于一个小文件来说是可以理解的。我尝试了一个400 MB的文件,压缩后它变成628 mb。怎么了?看代码。 (.net 2.0)

Public Sub Compress(ByVal infile As String, ByVal outfile As String)
    Dim sourceFile As FileStream = File.OpenRead(inFile)
    Dim destFile As FileStream = File.Create(outfile)

    Dim compStream As New GZipStream(destFile, CompressionMode.Compress)

    Dim myByte As Integer = sourceFile.ReadByte()
    While myByte <> -1
        compStream.WriteByte(CType(myByte, Byte))
        myByte = sourceFile.ReadByte()
    End While

    sourceFile.Close()
    destFile.Close()
End Sub

4 个答案:

答案 0 :(得分:4)

如果基础文件本身高度不可预测(已经压缩或大部分随机),那么尝试压缩它将导致文件变大。

从400到628Mb听起来非常不可能作为扩展因素,因为deflate算法(用于GZip)倾向于maximum expansion factor of 0.03% GZip报头的开销应该可以忽略不计。

编辑:4.0 c#版本表明压缩库已得到改进,不会导致不可压缩数据的显着扩展。这表明他们没有实现“回退到原始流块”模式。尝试使用SharpZipLib的库作为快速测试。当流通过放气不可压缩时,这应该为您提供接近相同的性能。如果确实考虑转向该版本或等待4.0版本以获得更高性能的BCL实现。请注意,强烈缺乏压缩表明您无论如何都无法进一步压缩

答案 1 :(得分:2)

你确定逐字节写入流是一个非常好的主意吗?它肯定没有理想的性能特征,也许这也是混淆gzip压缩算法的原因。

此外,您尝试压缩的数据可能不会真正可压缩。如果我是你,我会尝试使用与文本文档大小相同的文本文档,而不是随机二进制文件。

此外,您可以尝试使用纯DeflateStream而不是GZipStream,因为它们都使用相同的压缩算法(deflate),唯一的区别是gzip添加了一些额外的数据(如错误检查),因此DeflateStream可能会产生更小的结果

我的VB.NET有点生疏,所以我宁愿不尝试在VB.NET中编写代码示例。相反,这就是你应该如何在C#中实现它,将它转换为VB.NET对于有经验的人来说应该是相对简单的:(或者也许擅长VB.NET的人可以编辑我的帖子并将其翻译为VB.NET)

FileStream sourceFile;
GZipStream compStream;

byte[] buffer = new byte[65536];
int bytesRead = 0;
while (bytesRead = sourceFile.Read(buffer, 0, 65536) > 0)
{
     compStream.Write(buffer, 0, bytesRead);
}

答案 2 :(得分:1)

这是known anomaly,内置GZipStream(和DeflateStream)。
我可以想到两个解决方法:

  • 使用替代压缩机。
  • 构建一些逻辑,检查“压缩”输出的大小,并将其与输入的大小进行比较。如果更大,则清除输出并仅存储数据。

DotNetZip包含基于zlib托管端口的“固定”GZipStream。 (它从上面采取方法#1)。 Ionic.Zlib.GZipStream可以使用简单的命名空间交换替换应用程序中的内置GZipStream。

答案 3 :(得分:0)

谢谢大家的好答案。早些时候我试图压缩.wmv文件和一个文本文件。我将代码更改为DeflateStream,它现在似乎正常工作。欢呼声。

相关问题