使用 Ionic 创建大型多部分 zip 失败并出现 OutOfMemoryException
Creating large multi-part zip with Ionic fails with OutOfMemoryException
我尝试使用 IonicZip 创建一个总大小为 17 GB 的多部分 zip 文件。
每个 zip 部分设置为不大于 500 MB 左右。
zip.MaxOutputSegmentSize = 500000000;
进入 zip 的文件大小各不相同,但绝不会超过 350MB,通常要小得多,只有几 KB 或 MB。
我创建 zip 文件的机器有 4GB 内存。
当我在我的程序中开始创建 zip 时,由于使用了 RAM,我在某个时候得到了一个 OutOfMemoryException
。
(当所有文件的总大小约为 2 GB 而不是 17GB 时,同样可以正常工作)。
代码:
ZipFile zip = new ZipFile(zipFileName, Encoding.UTF8);
zip.CompressionLevel = CompressionLevel.BestCompression;
zip.ParallelDeflateThreshold = -1; //
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 在内部到底在做什么,直到它吐出第一个 zip 部分。
抱歉,我是 C# 和 .NET 的新手。 IonicZip 是最好的库吗?我可以改用 System.IO.Compression 或 System.IO.Packaging 包(我没有看到它们支持多部分压缩)或商业 Xceed 吗?
我已经检查但没有帮助的帖子:
- Compression fails when using ionic zip
- Ionic zip throws out of memory exception
- OutOfMemoryException when creating large ZIP file using System.IO.Packaging(与 IonicZip 无关)
我建议使用内置的 .net System.IO.Compression 命名空间 类 到 zip/unzip 文件;它们是基于流的,而您在此处的示例不使用流 - 因此必须使用 RAM 来存储压缩数据。使用 .net 本机库,您可以将压缩数据分块写入输出流。
我提出的解决方案在工作量方面似乎是最好的(我不想重新发明轮子并为标准 zip/compression 包编写多部分逻辑,似乎这种标准的东西应该是任何压缩包的一部分)是使用 Xceed 并且几乎使用与我为 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);
我尝试使用 IonicZip 创建一个总大小为 17 GB 的多部分 zip 文件。
每个 zip 部分设置为不大于 500 MB 左右。
zip.MaxOutputSegmentSize = 500000000;
进入 zip 的文件大小各不相同,但绝不会超过 350MB,通常要小得多,只有几 KB 或 MB。
我创建 zip 文件的机器有 4GB 内存。
当我在我的程序中开始创建 zip 时,由于使用了 RAM,我在某个时候得到了一个 OutOfMemoryException
。
(当所有文件的总大小约为 2 GB 而不是 17GB 时,同样可以正常工作)。
代码:
ZipFile zip = new ZipFile(zipFileName, Encoding.UTF8);
zip.CompressionLevel = CompressionLevel.BestCompression;
zip.ParallelDeflateThreshold = -1; //
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 在内部到底在做什么,直到它吐出第一个 zip 部分。
抱歉,我是 C# 和 .NET 的新手。 IonicZip 是最好的库吗?我可以改用 System.IO.Compression 或 System.IO.Packaging 包(我没有看到它们支持多部分压缩)或商业 Xceed 吗?
我已经检查但没有帮助的帖子:
- Compression fails when using ionic zip
- Ionic zip throws out of memory exception
- OutOfMemoryException when creating large ZIP file using System.IO.Packaging(与 IonicZip 无关)
我建议使用内置的 .net System.IO.Compression 命名空间 类 到 zip/unzip 文件;它们是基于流的,而您在此处的示例不使用流 - 因此必须使用 RAM 来存储压缩数据。使用 .net 本机库,您可以将压缩数据分块写入输出流。
我提出的解决方案在工作量方面似乎是最好的(我不想重新发明轮子并为标准 zip/compression 包编写多部分逻辑,似乎这种标准的东西应该是任何压缩包的一部分)是使用 Xceed 并且几乎使用与我为 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);