5

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 is causing OutOfMemoryException. Could someone tell what's right way to upload large files using such a handler?

2
  • 99% of the time, using a BinaryReader/Writer is a very wrong choice. Commented May 29, 2012 at 8:46
  • There are two answers given, do they do the same job? If not, which one is better over the other, and why? Commented May 29, 2012 at 8:52

2 Answers 2

7

There is no need to load a file into memory to write it to somewhere. You should be using a small buffer (maybe 8k), and looping over the streams. Or, with 4.0, the CopyTo method. For example:

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

(which does the small-buffer/loop for you, using a 4k buffer by default, or allowing a custom buffer-size to be passed via an overload)

Sign up to request clarification or add additional context in comments.

Comments

4

You get an OutOfMemoryException because you load your uploaded file into memory. Avoid this by writing your stream directly to a 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: removed binaryreader

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.