在内存不足的内存流中创建ziparchive本机C# [英] Create ziparchive native c# out of memory memorystream

查看:175
本文介绍了在内存不足的内存流中创建ziparchive本机C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用内置功能来制作zip system.io.compression.ziparchive

https://msdn.microsoft.com/zh-CN/library/system.io.compression.ziparchive.getentry%28v=vs.110%29.aspx

得到了:

mscorlib.dll中发生了'System.OutOfMemoryException'类型的异常,但未在用户代码中处理

我已阅读以下内容: ZipArchive创建无效的ZIP文件 这是我在* .ashx文件(网络表单)中的一些代码:

Dictionary<string, string> csvs = new Dictionary<string, string>();
using (var memoryStream = new MemoryStream())
{
    using (var zip = new ZipArchive(memoryStream, ZipArchiveMode.Update, true))
    {
        // start loop for 2000 products
        zip.CreateEntryFromFile(prodImg, brandName + @"\" + dr["ProductPictureName"]);
        // per product CreateEntryFromFile * 4

        // more lines
        csvs[tmpName] = value + sb.ToString();
    }
}
memoryStream.Seek(0, SeekOrigin.Begin);
context.Response.BinaryWrite(memoryStream.ToArray());
context.Response.Flush();
context.Response.Close();
context.Response.End();

我也已经阅读过此 https://stackoverflow.com/a/15869303/169714 ,却一无所知. ..

当我将stringbuilder的输出附加到类型为<string, string>的字典中时,我已经注释掉了一些行并耗尽了内存

有趣的是,当我使用DotNetZip nuget时,它起作用了 https://dotnetzip.codeplex.com/ 但是我更喜欢本机框架,而不是另一个nuget.

我已阅读此书,并可以验证该邮编不超过500mb

两个选项都不起作用.

您需要避免MemoryStream,并尝试尽快写入输出流.也许像这样可以帮助您.

using (var zip = new ZipArchive(context.Response.OutputStream, ZipArchiveMode.Update, true))
{
    // start loop for 2000 products
    zip.CreateEntryFromFile(prodImg, brandName + @"\" + dr["ProductPictureName"]);
    // per product CreateEntryFromFile * 4

    // more lines
    // csvs[tmpName] = value + sb.ToString(); // Also avoid the dictionary and the StringBuilder if you were using it just for debugging.
}

希望有帮助.

I am using the build in feature to make a zip system.io.compression.ziparchive

https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive.getentry%28v=vs.110%29.aspx

and got:

An exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll but was not handled in user code

I have read this: ZipArchive creates invalid ZIP file and this is some of my code in an *.ashx file (webforms):

Dictionary<string, string> csvs = new Dictionary<string, string>();
using (var memoryStream = new MemoryStream())
{
    using (var zip = new ZipArchive(memoryStream, ZipArchiveMode.Update, true))
    {
        // start loop for 2000 products
        zip.CreateEntryFromFile(prodImg, brandName + @"\" + dr["ProductPictureName"]);
        // per product CreateEntryFromFile * 4

        // more lines
        csvs[tmpName] = value + sb.ToString();
    }
}
memoryStream.Seek(0, SeekOrigin.Begin);
context.Response.BinaryWrite(memoryStream.ToArray());
context.Response.Flush();
context.Response.Close();
context.Response.End();

I have also read this https://stackoverflow.com/a/15869303/169714 and have no idea...

I have commented out some lines and get an out of memory when I append the output of a stringbuilder to a dictionary of type <string, string>

The funny thing is that when I used the DotNetZip nuget, it worked https://dotnetzip.codeplex.com/ But I prefer native framework rather then another nuget.

I have read this and can verify that the zip will not exceed 500mb http://bhrnjica.net/2012/07/22/with-net-4-5-10-years-memory-limit-of-2-gb-is-over/

ps seems to be related to having 8000 times CreateEntryFromFile tried to add CompressionLevel.NoCompression to reduce memory footprint, but did not solve my out of memory.

edit 2: I have reduced the 4 different images per product to just one for testing purposes and still have out of memory. Tried to move from CreateEntryFromFile to a more manual method...

//zip.CreateEntryFromFile(prodImg, brandName + @"\" + dr["ProductPictureName"], CompressionLevel.NoCompression);
ZipArchiveEntry zae = zip.CreateEntry(brandName + @"\" + dr["ProductPictureName"]);
using (var fileStream = File.OpenRead(prodImg))
{
    fileStream.CopyTo(zae.Open());
}

Both options do not work.

解决方案

You need to avoid the MemoryStream, and try to write to the output stream as soon as possible. Maybe something like this can help.

using (var zip = new ZipArchive(context.Response.OutputStream, ZipArchiveMode.Update, true))
{
    // start loop for 2000 products
    zip.CreateEntryFromFile(prodImg, brandName + @"\" + dr["ProductPictureName"]);
    // per product CreateEntryFromFile * 4

    // more lines
    // csvs[tmpName] = value + sb.ToString(); // Also avoid the dictionary and the StringBuilder if you were using it just for debugging.
}

Hope that helps.

这篇关于在内存不足的内存流中创建ziparchive本机C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆