OutOfMemoryException when send big file 500MB using FileStream ASPNET

前端 未结 4 819
北海茫月
北海茫月 2020-12-01 08:26

I\'m using Filestream for read big file (> 500 MB) and I get the OutOfMemoryException.

I use Asp.net , .net 3.5, win2003, iis 6.0

I want this in my app:

4条回答
  •  -上瘾入骨i
    2020-12-01 09:10

    I came across this question in my search to return a FileStreamResult from a controller, as I kept running into issues while working with large streams due to .Net trying to build the entire response all at once. Pavel Morshenyuk's answer was a huge help, but I figured I'd share the BufferedFileStreamResult that I ended up with.

    /// Based upon https://stackoverflow.com/a/3363015/595473 
    public class BufferedFileStreamResult : System.Web.Mvc.FileStreamResult
    {
        public BufferedFileStreamResult(System.IO.Stream stream, string contentType, string fileDownloadName)
            : base(stream, contentType)
        {
            FileDownloadName = fileDownloadName;
        }
    
        public int BufferSize { get; set; } = 16 * 1024 * 1024;//--16MiB
    
        protected override void WriteFile(System.Web.HttpResponseBase response)
        {
            try
            {
                response.Clear();
                response.Headers.Set("Content-Disposition", $"attachment; filename={FileDownloadName}");
                response.Headers.Set("Content-Length", FileStream.Length.ToString());
    
                byte[] buffer;
                int bytesRead;
    
                while (response.IsClientConnected)//--Prevent infinite loop if user disconnects
                {
                    buffer = new byte[BufferSize];
    
                    //--Read the data in buffer
                    if ((bytesRead = FileStream.Read(buffer, 0, BufferSize)) == 0)
                    {
                        break;//--Stop writing if there's nothing left to write
                    }
    
                    //--Write the data to the current output stream
                    response.OutputStream.Write(buffer, 0, bytesRead);
    
                    //--Flush the data to the output
                    response.Flush();
                }
            }
            finally
            {
                FileStream?.Close();
                response.Close();
            }
        }
    }
    

    Now, in my controller, I can just

    return new BufferedFileStreamResult(stream, contentType, fileDownloadName);
    

提交回复
热议问题