使用System.IO.Packaging创建大型ZIP文件时出现OutOfMemoryException异常

6
我正在尝试调试一个OutOfMemoryException,当使用System.IO.Packaging.ZipPackage创建一个相当大的ZIP文件时会出现该异常。
代码正在遍历一个大型对象列表,对于每个对象执行以下操作:
  1. 将对象数据序列化到临时文件中。
  2. 为该文件创建一个PackagePart
  3. 从源System.IO.Stream复制到另一个:
    • 源流:FileStream
    • 目标流:PackagePart::GetStream() => MS.Internal.IO.Zip.ZipIOModeEnforcingStream
最后调用Package::Close()保存文件。
我遇到的问题是,对于特别大的对象列表,我看到一个OutOfMemoryException(x86进程大小达到约1.2GB)。
我考虑将对象数据分成块,这样我每次只处理较小的数量(即上述步骤1-3)。我的想法是在临时目录中创建n个ZIP文件,然后找到一种方法将它们合并成一个单一的存档文件。
使用System.IO.Packaging是否可能实现此功能?我应该使用什么来合并这些部分?
还是有更好的方法来解决这个问题?

尝试在创建新包时迭代之间调用Flush。 - Ankur
@Ankur - 你做得很好,看起来这就是解决方法。如果你把你的评论升级为一个答案,我会很乐意接受它。 - LeopardSkinPillBoxHat
2个回答

3

在创建新的软件包之间调用Package对象上的Flush方法可能会解决问题,因为这将导致内存缓冲区刷新到磁盘。


谢谢 - 这对我有用。最终我在每添加500个文件到ZIP文件后都进行了清除。这是内存和性能之间的一个很好的权衡。 - LeopardSkinPillBoxHat

0

我会使用DotNetZip库(http://dotnetzip.codeplex.com/)。我尝试过几个压缩库(像你目前正在使用的System.IO和SharpZibLib),到目前为止,最容易使用的是DotNetZip库。

你几乎肯定会用更少的代码行,并且我发现内存使用非常好(在虚拟机环境中遇到了一个问题,我报告了它,新版本修复了它)。


我的原始问题对此并不是很清楚,但实际上这是现有代码中的一个缺陷,我不想太多地重新编写这段代码(我只想修复崩溃)。我编辑了问题以使其更加明确。 - LeopardSkinPillBoxHat

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