我尝试使用IonicZip创建一个包含总大小为17 GB的文件的多部分zip文件。
每个zip部件设置为不大于500 MB。
zip.MaxOutputSegmentSize = 500000000;
进入zip的文件各有各种尺寸,但绝不会超过350MB,通常要小得多,只需几KB或MB。
我创建zip文件的机器有4GB RAM。
当我在程序中开始创建zip时,由于使用了RAM,我在某个时刻会得到OutOfMemoryException
。
(当所有文件的总大小约为2 GB而不是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.save。没有必要将所有多部分保存在内存中但只保留当前部分,而不是?
由于我将zip.MaxOutputSegmentSize设置为仅大约500MB,并且进入zip的单个文件的最大大小不超过350MB,我不明白为什么它会占用这么多内存。
另一方面,当发生OutOfMemoryException时,甚至没有任何单个部分写入磁盘。通常,在zip创建成功的文件数量较少的情况下,文件系统中的多个部分具有不同的创建时间戳,大约为。每个相隔5秒。所以我真的不确定IonicZip内部做了什么,直到它吐出第一个拉链部分。
抱歉,我是C#和.NET的新手。 IonicZip是最好的库吗?我可以使用System.IO.Compression或System.IO.Packaging包(我没有看到它们支持多部分拉链)或商业Xceed吗?
我已经检查但没有帮助的帖子:
答案 0 :(得分:0)
我建议使用内置的.net System.IO.Compression命名空间类来压缩/解压缩文件;它们是基于流的,而您的示例不使用流 - 因此必须使用RAM来存储压缩数据。使用.net本机库,您可以将压缩数据以块的形式写入输出流。
答案 1 :(得分:0)
我想出的解决方案似乎是努力方面的最佳解决方案(我不想重新发明轮子并为标准的压缩/压缩包编写多部分逻辑,似乎是这样的标准的东西应该是任何压缩包的一部分)是使用http://ktoso.github.io/scala-types-of-types/并且几乎使用与IonicZip相同的代码逻辑。
似乎IonicZip在内存方面并没有真正有效地处理它。 Xceed工作正常,内存使用量没有大幅增加。
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);