ASP.NET C # OutofMemoryException when loading a large file

I have the following file upload handler:

public class FileUploader : IHttpHandler { public void ProcessRequest(HttpContext context) { HttpRequest request = context.Request; context.Response.ContentType = "text/html"; context.Response.ContentEncoding = System.Text.Encoding.UTF8; context.Response.Cache.SetCacheability(HttpCacheability.NoCache); var tempPath = request.PhysicalApplicationPath + "\\Files\\TempFiles\\"; byte[] buffer = new byte[request.ContentLength]; using (BinaryReader br = new BinaryReader(request.InputStream)) { br.Read(buffer, 0, buffer.Length); } var tempName = WriteTempFile(buffer, tempPath); context.Response.Write("{\"success\":true}"); context.Response.End(); } public bool IsReusable { get { return true; } } private string WriteTempFile(byte[] buffer, string tempPath) { var fileName = GetUniqueFileName(tempPath); File.WriteAllBytes(tempPath + fileName, buffer); return fileName; } private string GetUniqueFileName(string tempPath) { var guid = Guid.NewGuid().ToString().ToUpper(); while (File.Exists(tempPath + guid)) { guid = Guid.NewGuid().ToString().ToUpper(); } return guid; } } 

When I upload large files, this raises an OutOfMemoryException. Can anyone tell me how to properly upload large files using such a handler?

+4
source share
2 answers

There is no need to load the file into memory to write it somewhere. You should use a small buffer (maybe 8k) and iterate over the threads. Or, from 4.0, the CopyTo method. For instance:

 using(var newFile = File.Create(tempPath)) { request.InputStream.CopyTo(newFile); } 

(which makes a small buffer / loop for you, using the default 4-kilobyte buffer or allowing you to pass your own buffer size through overload)

+7
source

You get an OutOfMemoryException because you are loading the downloaded file into memory. Avoid this by writing the stream directly to the file.

 public void ProcessRequest(HttpContext context) { const int BufferSize = 4096; HttpRequest request = context.Request; context.Response.ContentType = "text/html"; context.Response.ContentEncoding = System.Text.Encoding.UTF8; context.Response.Cache.SetCacheability(HttpCacheability.NoCache); var tempFilePath = Path.GetTempFileName(); using (Stream fs = File.OpenWrite(tempFilePath)); { byte[] buffer = new byte[BufferSize]; int read = -1; while(read = request.InputStream.Read(buffer, 0, buffer.Length) > 0) { fs.Write(buffer, 0, buffer.Length); } } context.Response.Write("{\"success\":true}"); context.Response.End(); } 

edit: remote binaryreader

+4
source

Source: https://habr.com/ru/post/1414841/


All Articles