使用 System.IO.Packaging 创建大型 ZIP 文件时出现 OutOfMemoryException
我正在尝试调试使用 System.IO.Packaging.ZipPackage 创建相当大的 ZIP 文件时发生的 OutOfMemoryException 。
该代码迭代大量对象,对每个对象执行以下操作。
- 将对象数据序列化到临时文件。
- 为文件创建一个
PackagePart
。 - 从源 System.IO.Stream 复制到另一个源:
- 源流:
FileStream
- 目标流:
PackagePart::GetStream()
=>MS.Internal.IO.Zip.ZipIOModeEnforcingStream
- 源流:
最后调用 Package::Close()
来保存文件。
我遇到的问题是,对于一个特别大的对象列表,我看到一个 OutOfMemoryException
(x86 进程大小达到大约 1.2GB)。
我正在考虑将对象数据分区为块,因此每个循环只处理较小的数据量(即上面的步骤 1-3)。我的想法是,我将在临时目录中创建 n 个 ZIP 文件,然后找到一种方法将它们组合成一个存档。
使用 System.IO.Packaging 可以实现这一点吗?我将使用什么来组合这些部件?
或者有更好的方法来解决这个问题吗?
I am trying to debug an OutOfMemoryException
that occurs when creating a fairly large ZIP
file using System.IO.Packaging.ZipPackage
.
The code is iterating through a large list of objects, doing the following for each object.
- Serializing the object data to a temporary file.
- Creating a
PackagePart
for the file. - Copy from a source
System.IO.Stream
to another:- Source stream:
FileStream
- Target stream:
PackagePart::GetStream()
=>MS.Internal.IO.Zip.ZipIOModeEnforcingStream
- Source stream:
Finally it calls Package::Close()
which saves the file.
The problem I am having is that for a particularly large list of objects, I am seeing an OutOfMemoryException
(the x86 process size is getting to about 1.2GB in size).
I was thinking about partitioning the object data into chunks so I only process a smaller amount per loop (i.e. steps 1-3 above). The idea is that I would create n
ZIP files in a temporary directory, and then find a way to combine them into a single archive.
Is this possible using System.IO.Packaging
? What would I use to combine the parts?
Or is there a better way to fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在创建新包之间调用 Package 对象上的
Flush
方法可能应该可以解决问题,因为这会导致内存缓冲区刷新到磁盘。Calling the
Flush
method on the Package object in between creating a new package should probably solve the problem as that would cause the memory buffer to be flushed to disk.我将使用 DotNetZip 库 (http://dotnetzip.codeplex.com/)。我已经尝试了几个 zip 库(像您当前正在使用的 System.IO 以及 SharpZibLib),到目前为止,最容易使用的是 DotNetZip 库。
几乎可以肯定,您最终会得到更少的代码行,而且我发现内存使用情况非常好(在虚拟机环境中遇到了问题,我报告了该问题,新版本修复了该问题)。
I would use the DotNetZip library (http://dotnetzip.codeplex.com/). I've tried several zip libraries (System.IO like you are currently using and also SharpZibLib) and by far the easiest to use is the DotNetZip library.
You'll almost certainly end up with fewer lines of code and I found the memory usage to be very good (had a problem in a virtual machine environment which I reported and a new release fixed it).