Create ziparchive native c# out of memory memorystream

三世轮回 提交于 2019-12-12 06:23:37

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/33894385/create-ziparchive-native-c-sharp-out-of-memory-memorystream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!