DotNetZip会创建损坏的存档文件(CRC校验错误)

4

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变得奇怪。嗯,要么是这样,要么是我误解了什么 :)

2
“GetBuffer” 明显是错误的,因为缓冲区通常比内容大。请使用 “ToArray()”。或者在消费代码中仔细处理未完全填充的缓冲区。 - CodesInChaos
我很高兴我们解决了这个问题。你能把那个评论加上去,这样我就可以接受它作为答案吗? - Heki
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
6
GetBuffer是错误的。它返回MemoryStream的内部缓冲区,通常比实际内容更大。 要返回仅包含实际内容的数组,请使用ToArray()。 或者您可以在消费代码中仔细处理未完全填充的缓冲区。这将减少GC压力,因为您不需要为返回值分配整个新数组。 如果zip归档文件很大,我还会考虑直接保存到文件,而不是在内存中组装归档文件。

谢谢,CodeInChaos。你在这里提出了一些好的观点。处理缓冲区应该是删除所有尾随的0字节吗? - Heki
1
这取决于调用代码。它将涉及传递有效数据的长度,并适当地处理它。您不能认为所有尾随的 0 字节都是无效的,只有超出 ms.Length 的那些才是。 - CodesInChaos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,