【问题标题】:GZipStream not compressing?GZipStream 不压缩?
【发布时间】:2011-06-06 16:42:21
【问题描述】:

我正在尝试将内存流压缩到另一个内存流中,以便上传到休息 API。 image 是包含 tif 图像的初始内存流。

WebRequest request = CreateWebRequest(...);
request.ContentType = "application/zip";
MemoryStream zip = new MemoryStream();
GZipStream zipper = new GZipStream(zip, CompressionMode.Compress);
image.CopyTo(zipper);
zipper.Flush();
request.ContentLength = zip.Length; // zip.Length is returning 0
Stream reqStream = request.GetRequestStream();
zip.CopyTo(reqStream);
request.GetResponse().Close();
zip.Close();

据我了解,我写入 GZipStream 的任何内容都将被压缩并写入传递给其构造函数的任何流。当我将图像流复制到拉链中时,实际上没有复制任何内容(图像为 200+ MB)。这是我第一次使用 GZipStream,所以我可能遗漏了一些东西,任何关于什么将不胜感激的建议。

编辑: 我应该注意到这对我来说是个问题,在上面的代码中,image 的位置位于流的最末端......因此,当我调用 image.CopyTo(zipper); 时,由于该位置,没有任何内容被复制。

【问题讨论】:

  • 请注意:如果您的 TIFF 已经压缩(我认为大多数是压缩的),您将不会得到非常令人印象深刻的结果。
  • 这些是未压缩的 GeoTiff。此外,我上传这些图像的 REST API 要求上传是 zip。

标签: c# compression


【解决方案1】:

[已编辑:删除有关 GZipStream 及其构造函数参数的不正确信息,并使用 real 答案进行了更新 :) ]

复制到拉链后,您需要将 MemoryStream 的位置移回零,因为拉链写入内存流的过程会推进它的“光标”以及正在读取的流:

WebRequest request = CreateWebRequest(...);
request.ContentType = "application/zip";
MemoryStream zip = new MemoryStream();
GZipStream zipper = new GZipStream(zip, CompressionMode.Compress);
image.CopyTo(zipper);
zipper.Flush();
zip.Position = 0; // reset the zip position as this will have advanced when written to.
...

还有一点需要注意的是,GZipStream 是不可搜索的,所以调用 .Length 会抛出异常。

【讨论】:

  • +1 用于解释 GZipStream 不可搜索,但 MSDN 示例将数据添加到 GZip 流之后创建它(不是底层流)。 OP没有误解
  • zipper.CopyTo(reqStream) 抛出异常。无法读取拉链。
  • 多次阅读thekip的链接MSDN文章后,我越看你的例子......我越觉得你误解了GZipStream。
【解决方案2】:

我对 C# 及其库一无所知,但我会先尝试使用Close 而不是(或之后)Flush

(Java 的 GZipOutputStream 存在同​​样的问题,即在 Java 7 之前它无法正确刷新。)

【讨论】:

【解决方案3】:

【讨论】:

  • 除了 using 语句之外,我看不出示例所做的与我正在做的有什么区别。我确实计划在我开始工作时添加 using 语句,在此之前我不希望它们对范围内的内容造成严重破坏。
  • 打电话Flush()有什么问题?这似乎完全合法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多