【问题标题】:DotNetZip Creates corrupt archives (bad CRC)DotNetZip 创建损坏的存档(CRC 错误)
【发布时间】:2012-04-24 06:57:45
【问题描述】:

DotNetZip 有一个奇怪的问题,我似乎找不到解决方案。 我已经搜索了几个小时,但我找不到任何关于此的内容,所以就这样吧。

var ms = new MemoryStream();
using (var archive = new Ionic.Zip.ZipFile()) {
    foreach (var file in files) {
        //                                string     byte[]
        var entry = archive.AddEntry(file.Name, file.Data);
        entry.ModifiedTime = DateTime.Now.AddYears(10); // Just for testing
    }
    archive.Save(ms);
}
return ms.GetBuffer();

我需要添加修改时间,这很关键,但现在我只有一个虚拟时间戳。

当我用 WinRAR 打开文件时,它显示“存档意外结束”。每个单独的文件都有校验和 00000000,WinRAR 显示“存档格式未知或已损坏”。我可以修理它,这使它的尺寸缩小了 20%,一切正常。但这并不是真的有用..

当我在添加所有条目后创建断点时,我可以在zip.Entries 中看到所有条目都具有相同的错误 CRC,但所有数据似乎都在那里。 所以问题不应该是我保存存档的方式。

我在其他地方使用我的文件集合没有问题,这增加了 DotNetZip 的奇怪之处。好吧,或者我误解了一些东西:)

【问题讨论】:

  • GetBuffer 肯定是错误的,因为缓冲区通常大于内容。使用ToArray()。或者小心处理消费代码中未完全填充的缓冲区。
  • 我很高兴我们解决了这个问题。它实际上解决了这个问题。您可以将该评论添加为答案,以便我可以接受它吗?

标签: c# zip checksum dotnetzip


【解决方案1】:

GetBuffer 肯定是错误的。它返回MemoryStream 的内部缓冲区,通常比实际内容大。

要返回一个只包含实际内容的数组,请使用ToArray()

或者您可以小心处理消费代码中未完全填充的缓冲区。这将减少 GC 压力,因为您不需要为返回值分配一个全新的数组。

如果 zip 存档很大,我也会考虑直接保存到文件中,而不是在内存中组装存档。

【讨论】:

  • 谢谢,CodeInChaos。你在这里有一些好处。缓冲区的处理将删除所有尾随的 0 字节?
  • 这取决于调用代码。这相当于传递有效数据的长度,并对其进行适当处理。您不能认为所有尾随 0 字节无效,只有 ms.Length 之外的字节无效。
猜你喜欢
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
相关资源
最近更新 更多