blue
blue

Reputation: 863

asp.net large file download out of memory exception

I'm trying to download a file with size greater than 50mb in an asp.net page. But it fails on our production server. It works on development and QA servers. I'm using the following code.

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

The error I'm getting from the server is as below.

Page_Load System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at System.IO.BinaryReader.ReadBytes(Int32 count) at ExportDoc.Page_Load(Object sender, EventArgs e) in c:\sitename\ExportDoc.aspx.vb:line 87 Server Name

What is wrong with the code?

Upvotes: 2

Views: 2021

Answers (2)

blue
blue

Reputation: 863

I tried the below code and it resolved my issue, found the code idea from MSDN website.

                  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

Upvotes: 0

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

OutOfMemoryException commonly thrown when there is no available memory to perform such operation when handling both managed/unmanaged resources. Therefore, you need to use Using...End Using block wrapping around BinaryReader to guarantee immediate disposal of unmanaged resources after usage with IDisposable interface:

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

Another common usage of BinaryReader is using FileStream and a byte buffer to control file reading mechanism:

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

References:

VB.NET Using Statement (MSDN)

BinaryReader Class (MSDN)

Upvotes: 2

Related Questions