我使用下面的代码来压缩文件,它们不断增长而不是缩小。我压缩了一个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
答案 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,它现在似乎正常工作。欢呼声。