2012-05-29 30 views
4

我有以下文件上传处理:ASP.NET C#OutOfMemoryException异常在大文件的上传

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; 
} 
} 

当我上传大文件,这是导致OutOfMemoryException异常。有人能说出使用这种处理程序上传大文件的正确方法吗?

+0

99%取出,用'BinaryReader在/ Writer'是一个非常错误的选择。 – leppie

+0

有两个答案,他们做同样的工作吗?如果不是,哪一个比另一个更好,为什么? –

回答

7

不需要将文件加载到内存中以将其写入到某处。你应该使用一个小的缓冲区(也许8k),并循环流。或者,用4.0,即CopyTo方法。例如:

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

(其中不小的缓冲器/环路对你来说,使用4k的缓冲区默认情况下,或允许自定义缓存大小通过过载传递)

+0

是的,这是它!忘记我的回答:) –

4

你得到的OutOfMemoryException,因为您将上载的文件加载到内存中。 避免将此流直接写入文件。

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(); 
} 

编辑:BinaryReader在时间