使用Ionic创建大型多部分zip失败,导致OutOfMemoryException
本文关键字:失败 导致 OutOfMemoryException zip Ionic 创建 大型 多部 使用 | 更新日期: 2023-09-27 18:03:08
我尝试使用IonicZip创建一个总大小为17gb的多部分zip文件。
每个zip部分设置为不超过500mb左右。
zip.MaxOutputSegmentSize = 500000000;
压缩文件的大小各不相同,但不会超过350MB,通常要小得多,只有几个KB或MB。
我创建zip文件的机器有4GB内存。
当我在我的程序中开始zip创建时,由于使用的RAM,我在某些时候得到一个OutOfMemoryException
。
(当所有文件的总大小约为2gb而不是17GB时,同样可以正常工作)。
代码:
ZipFile zip = new ZipFile(zipFileName, Encoding.UTF8);
zip.CompressionLevel = CompressionLevel.BestCompression;
zip.ParallelDeflateThreshold = -1; // https://stackoverflow.com/questions/11981143/compression-fails-when-using-ionic-zip
zip.MaxOutputSegmentSize = 500000000; // around 500MB
[...]
while (...)
{
zip.AddEntry(adjustedFilePath, File.ReadAllBytes(filepath));
}
zip.Save();
我想知道IonicZip如何处理zip。结合多部分创建保存。它不应该是必要的持有所有的多部分在内存中,但只有当前一个,不是吗?
既然我设置了zip。MaxOutputSegmentSize仅为500MB左右,压缩后单个文件的最大大小从不超过350MB,我不明白为什么它要消耗这么多内存。
另一方面,当OutOfMemoryException发生时,甚至还没有将多部分的任何单个部分写入磁盘。通常,在成功创建zip文件的文件数量较少的情况下,大约有多个部分位于具有不同创建时间戳的文件系统上。每次间隔5秒。所以我真的不确定IonicZip内部到底在做什么,直到它吐出第一个zip部分。
对不起,我是c#和。net的新手。IonicZip是最好的库吗?我是否可以使用System.IO.Compression或System.IO.Packaging包(我没有看到它们支持多部分压缩)或商业Xceed?我已经检查过但没有帮助的帖子:
- 使用ionic zip压缩失败 Ionic zip抛出内存异常
- 使用System.IO.Packaging(与IonicZip无关)创建大型ZIP文件时出现OutOfMemoryException
我建议使用内置的。net System.IO.Compression命名空间类来压缩/解压缩文件;它们是基于流的,而您这里的示例不使用流-因此必须使用RAM来存储压缩数据。使用。net原生库,您可以将压缩后的数据块写入输出流。
我提出的解决方案似乎是最好的努力方面(我不想不得不重新发明轮子和编写多部分逻辑的标准zip/压缩包,似乎这样一个标准的事情,应该是任何压缩包的一部分)是使用Xceed和几乎使用相同的代码逻辑,就像我为IonicZip所做的。
似乎IonicZip在内存方面并没有真正有效地处理它。
using Xceed.Zip;
using Xceed.FileSystem;
[...]
ZipArchive zip = new ZipArchive(new DiskFile(zipFileName));
zip.SplitNameFormat = SplitNameFormat.PkZip;
zip.SplitSize = 500000;
zip.DefaultCompressionLevel = Xceed.Compression.CompressionLevel.Highest;
zip.TempFolder = new DiskFolder(@"C:'temp");
new DiskFolder(localSourceFolder).CopyFilesTo(zip, true, true);