asp.net大文件下载内存不足异常

asp.net large file download out of memory exception

我正在尝试在 asp.net 页面中下载一个大于 50mb 的文件。但它在我们的生产服务器上失败了。它适用于开发和 QA 服务器。我正在使用以下代码。

Response.Clear()
oBinaryReader = New System.IO.BinaryReader(System.IO.File.OpenRead(sDocPath))
lFileSize = Microsoft.VisualBasic.FileLen(sDocPath)
Response.AddHeader("Content-Disposition", "attachment;filename=" & sDownloadFileName)
Response.ContentType = "application/unknown"
Response.BinaryWrite(oBinaryReader.ReadBytes(lFileSize))
Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
Response.End()

我从服务器得到的错误如下。

Page_Load System.OutOfMemoryException:引发了“System.OutOfMemoryException”类型的异常。 在 System.IO.BinaryReader.ReadBytes(Int32 计数) 在 ExportDoc.Page_Load(Object sender, EventArgs e) in c:\sitename\ExportDoc.aspx.vb:line 87 Server Name

代码有什么问题?

OutOfMemoryException 通常在处理两个 managed/unmanaged 资源时没有可用内存来执行此类操作时抛出。因此,您需要使用 Using...End Using 块环绕 BinaryReader 以保证在使用 IDisposable 接口后立即处理非托管资源:

Response.Clear()

Using oBinaryReader As BinaryReader = New BinaryReader(File.OpenRead(sDocPath))
   lFileSize = FileLen(sDocPath)

   Response.AddHeader("Content-Disposition", "attachment;filename=" & sDownloadFileName)
   Response.ContentType = "application/unknown"
   Response.BinaryWrite(oBinaryReader.ReadBytes(lFileSize))
   Response.Flush()
   HttpContext.Current.ApplicationInstance.CompleteRequest()
   Response.End()
End Using

BinaryReader 的另一个常见用法是使用 FileStream 和字节缓冲区来控制文件读取机制:

Using FStream As FileStream = New FileStream(File.OpenRead(sDocPath))
   lFileSize = CType(FStream.Length, Integer)
   Dim Buffer() As Byte

   Using oBinaryReader As BinaryReader = New BinaryReader(FStream)
      Buffer = oBinaryReader.ReadBytes(lFileSize)
   End Using

   Response.Clear()
   Response.AddHeader("Content-Disposition", "attachment;filename=" & sDownloadFileName)
   Response.ContentType = "application/unknown"
   Response.BinaryWrite(Buffer)
   Response.Flush()
   HttpContext.Current.ApplicationInstance.CompleteRequest()
   Response.End()
End Using

参考文献:

VB.NET Using Statement (MSDN)

BinaryReader Class (MSDN)

我尝试了下面的代码,它解决了我的问题,从 MSDN 网站找到了代码思路。

                  Using iStream As System.IO.Stream = New System.IO.FileStream(sDocPath, System.IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
                        dataToRead = iStream.Length
                        Response.ContentType = "application/octet-stream"
                        Response.AddHeader("Content-Disposition", "attachment; filename=" & filename)
                        While dataToRead > 0
                            If Response.IsClientConnected Then
                                length = iStream.Read(buffer, 0, bufferSize)
                                Response.OutputStream.Write(buffer, 0, length)
                                Response.Flush()
                                ReDim buffer(bufferSize)
                                dataToRead = dataToRead - length
                            Else
                                dataToRead = -1
                            End If
                        End While
                        HttpContext.Current.ApplicationInstance.CompleteRequest()
                    End Using