在c#.net中更新zip时出现内存不足异常

时间:2015-05-01 07:28:43

标签: c# .net out-of-memory

我在尝试在c#.net中的Zip文件中添加文件时遇到OutofMemoryException。我正在使用32位架构来构建和运行应用程序

            string[] filePaths = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\capture\\capture");
            System.IO.Compression.ZipArchive zip = ZipFile.Open(filePaths1[c], ZipArchiveMode.Update);

                foreach (String filePath in filePaths)

                {
                    string nm = Path.GetFileName(filePath);
                    zip.CreateEntryFromFile(filePath, "capture/" + nm, CompressionLevel.Optimal);
                }
                zip.Dispose();
                zip = null;

我无法理解背后的共鸣

2 个答案:

答案 0 :(得分:9)

确切原因取决于多种因素,但很可能只是简单地向存档添加了太多内容。请尝试使用ZipArchiveMode.Create选项,将存档直接写入磁盘而不将其缓存在内存中。

如果您确实尝试更新现有存档,仍可以使用ZipArchiveMode.Create。但它需要打开现有存档,将其所有内容复制到新存档(使用Create),然后添加新内容。

如果没有good, minimal, complete code example,就无法确定异常的来源,更不用说如何修复它。

修改

以下是我的意思" ...打开现有存档,将其所有内容复制到新存档(使用Create),然后添加新内容":

string[] filePaths = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\capture\\capture");

using (ZipArchive zipFrom = ZipFile.Open(filePaths1[c], ZipArchiveMode.Read))
using (ZipArchive zipTo = ZipFile.Open(filePaths1[c] + ".tmp", ZipArchiveMode.Create))
{
    foreach (ZipArchiveEntry entryFrom in zipFrom.Entries)
    {
        ZipArchiveEntry entryTo = zipTo.CreateEntry(entryFrom.FullName);

        using (Stream streamFrom = entryFrom.Open())
        using (Stream streamTo = entryTo.Open())
        {
            streamFrom.CopyTo(streamTo);
        }
    }

    foreach (String filePath in filePaths)
    {
        string nm = Path.GetFileName(filePath);
        zipTo.CreateEntryFromFile(filePath, "capture/" + nm, CompressionLevel.Optimal);
    }
}

File.Delete(filePaths1[c]);
File.Move(filePaths1[c] + ".tmp", filePaths1[c]);

或类似的东西。缺少一个好的最小完整的代码示例,我只是在浏览器中编写了上述内容。我没有尝试编译它,没关系测试它。您可能想要调整一些细节(例如临时文件的处理)。但希望你明白了。

答案 1 :(得分:-1)

原因很简单。 OutOfMemoryException意味着内存不足以执行。

压缩消耗大量内存。无法保证逻辑更改可以解决问题。但你可以考虑不同的方法来缓解它。

1。 由于您的主程序必须是32位,您可以考虑启动另一个64位进程来进行压缩(使用System.Diagnostics.Process.Start)。在64位进程完成其作业并退出后,您的32位主程序可以继续。您只需使用系统上已安装的工具,或自己编写一个简单的程序。

2。 另一种方法是每次添加条目时都要配置。 ZipArchive.Dispose保存文件。每次迭代后,可以释放为ZipArchive分配的内存。

            foreach (String filePath in filePaths)
            {
                System.IO.Compression.ZipArchive zip = ZipFile.Open(filePaths1[c], ZipArchiveMode.Update);
                string nm = Path.GetFileName(filePath);
                zip.CreateEntryFromFile(filePath, "capture/" + nm, CompressionLevel.Optimal);
                zip.Dispose();
            }

这种方法并不简单,可能不如第一种方法有效。