【问题标题】:GZipStream: Compressed file bigger than originalGZipStream:比原始文件大的压缩文件
【发布时间】:2014-03-15 19:26:36
【问题描述】:

我正在尝试在 C# 中使用 gzip 流,但压缩后的文件似乎比以前大。 当我使用 .avi 和 .mkv 文件时会发生这种情况。但是如果我使用比原始文件更小的 .txt 和 .html 压缩文件。

using (MemoryStream output = new MemoryStream(blockToCompress.Length))
{
     using (GZipStream cs = new GZipStream(output, CompressionMode.Compress))
     {
          cs.Write(blockToCompress, 0, blockToCompress.Length);
     }
}

我通过检查框架(从 3.5 到 4.0)解决了这个问题,而无需编辑代码。

【问题讨论】:

  • (大多数)视频文件已经被高度压缩,因此重新压缩通常会增加它们的大小。英文文本非常可压缩。
  • 这是一个重复的问题,请参考*.com/questions/3973485/…
  • 如果这些格式可以进一步压缩,那么所有视频提供商(如 youtube)都以该格式流式传输它们。
  • .NET 压缩代码很糟糕。使用外部库至少保持非常接近 100% 的不可压缩数据。

标签: c# gzipstream


【解决方案1】:

您的代码是正确的。不幸的是,您的期望并非如此。

大多数视频和音频文件已经被高度压缩。它们将无法像 GZip 一样使用lossless compression 进一步压缩。事实上,您可能会稍微增加文件大小 - 每种文件格式,包括 GZip,都会带来一些开销/簿记。

如果您确实需要减小它们的大小,则需要使用能够理解视频格式的lossy compression scheme。基本上,您将删除数据,可能会降低表观质量,以换取更小的数据。

如果源内容未压缩,则 GZip 等无损压缩方案可以将文件大小减少 25-50%。包含大量重复文本 (HTML) 或英文文本(一般文本文件)的文件通常压缩得更好。

【讨论】:

    【解决方案2】:

    您的 avi 和 mkv 文件与大多数媒体格式一样已经被严重压缩,gzip 可能无法进一步压缩它们,大小增加是一个但奇怪但根据 gzip 规范至少有一个标头标志字节,具体取决于在实现上,它可能会添加更多元数据。

    【讨论】:

      【解决方案3】:

      假设无损压缩算法能够压缩每个文件。这样您就可以再次压缩压缩输出并获得更小的文件,如果您只是一次又一次地压缩它,最终您可以将每个文件压缩为零大小。显然情况并非如此,其原因在于信息理论原理。但这也意味着对于每种压缩算法,都有一些文件无法压缩或会因压缩而增长。最后,由于压缩而增长的文件是具有高熵的文件,压缩的视频文件属于这一类,这就解释了你所看到的。

      【讨论】: