Getting Out of Memory Exception when downloading large files

BeUnique 2,332 Reputation points
2022-06-17T12:16:47.65+00:00

I developed ASP.NET web application. I am trying to download the document from file server. FileSize maybe more than 1GB.

Here the thing is, very first time file got downloaded. when i click the same link, i am getting "Out of memory Exception" throws error.

If it is small size file, i don't get any issues to download the filles...

How do we handle this error if i download the document more than 1GB...?

below is the code to download the file in ASP.NET (Code behind file)

 Dim binFile As Byte() = File.ReadAllBytes(filename)  
            Response.ContentType = "application/octet-stream"  
            Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename)  
            Response.BinaryWrite(binFile)  
            Response.End()  
Developer technologies ASP.NET Other
0 comments No comments
{count} votes

Accepted answer
  1. Lan Huang-MSFT 30,186 Reputation points Microsoft External Staff
    2022-06-20T07:54:11.787+00:00

    Hi @BeUnique ,
    If you only need a file download handler, use HttpResponse.TransmitFile() which don't buffer the file in memory.
    https://learn.microsoft.com/en-us/dotnet/api/system.web.httpresponse.transmitfile?redirectedfrom=MSDN&view=netframework-4.8#System_Web_HttpResponse_TransmitFile_System_String_
    Or try the code below, the meaning of the code is written in the comments.

    Public Sub Download(ByVal fileId As String)  
         //MAKE FILEPATH  
        Dim filePath As String = makeFilePath(fileId)  
        Dim outFileName As String = _info.FileName  
        Dim iStream As System.IO.Stream = Nothing  
        // Create buffer for reading [intBufferSize] bytes from file  
        Dim intBufferSize As Integer = 10 * 1024  
        Dim buffer As Byte() = New System.Byte(intBufferSize - 1) {}  
        // Length of the file That Really Has Been Read From The Stream and Total bytes to read  
        Dim length As Integer  
        Dim dataToRead As Long  
      
        If System.IO.File.Exists(filePath) Then  
      
            Try  
                // Open the file.  
                iStream = New System.IO.FileStream(path:=filePath, mode:=System.IO.FileMode.Open, access:=System.IO.FileAccess.Read, share:=System.IO.FileShare.Read)  
                // Total bytes to read:  
                dataToRead = iStream.Length  
                Response.Clear()  
                 // Setting the unknown [ContentType]  
                 // will display the saving dialog for the user  
                Response.ContentType = "application/octet-stream"  
                // With setting the file name,  
                // in the saving dialog, user will see  
                // the [outFileName] name instead of [download]!  
                Response.AddHeader("Content-Disposition", "attachment; filename=" & outFileName)  
                // Notify user (client) the total file length  
                Response.AddHeader("Content-Length", iStream.Length.ToString())  
                 // Read the bytes.  
                While dataToRead > 0  
                     // Verify that the client is connected.  
                    If Response.IsClientConnected Then  
                        // Read the data and put it in the buffer.  
                        length = iStream.Read(buffer:=buffer, offset:=0, count:=intBufferSize)  
                       // Write the data from buffer to the current output stream.  
                        Response.OutputStream.Write(buffer:=buffer, offset:=0, count:=length)  
                         // Flush (Send) the data to output  
                         // (Don't buffer in server's RAM!)  
                        Response.Flush()  
                        buffer = New Byte(intBufferSize - 1) {}  
                        dataToRead = dataToRead - length  
                    Else  
                        //prevent infinite loop if user disconnects  
                        dataToRead = -1  
                    End If  
                End While  
      
            Catch ex As Exception  
                Throw New ApplicationException(ex.Message)  
            Finally  
      
                If iStream IsNot Nothing Then  
                    //Close the file.  
                    iStream.Close()  
                    iStream = Nothing  
                End If  
      
                Response.Close()  
            End Try  
        End If  
    End Sub  
    

    Edit

    <asp:TreeView ID="TreeView1" runat="server" Font-Names="Trebuchet MS" Font-Size="15px" ForeColor="blue" Font-Bold="true" OnSelectedNodeChanged="TreeView1_SelectedNodeChanged">  
    <Nodes>  
    <asp:TreeNode>  
    <asp:TreeNode Text="Stud2" Value="Stud2" Target="_blank">  
    </asp:TreeNode>  
    </asp:TreeNode>  
    </Nodes>  
    </asp:TreeView>  
    Public Sub TreeView1_SelectedNodeChanged(sender As Object, e As EventArgs)  
            Dim filename = Server.MapPath("Test.pdf")  
            If File.Exists(filename) Then  
                Response.Clear()  
                Using oBinaryReader As BinaryReader = New BinaryReader(File.OpenRead(filename))  
                    Response.ContentType = "application/octet-stream"  
                    Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename)  
                    Response.TransmitFile(filename)  
                    Response.End()  
                End Using  
            End If  
        End Sub  
    

    213221-11.gif
    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


1 additional answer

Sort by: Most helpful
  1. AgaveJoe 30,126 Reputation points
    2022-06-17T12:37:03.227+00:00

    I think you used the wrong tag for this post. Is this really an ASP.NET Core question? The code looks like .NET Framework, maybe Web Forms??? If you posted in the wrong subject and this is actually a Web Forms question then try using...

    Response.TransmitFile(pathtoyourfile);  
    

    HttpResponse.TransmitFile Method

    Your current approach places the entire file in memory which is not a good approach for large files.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.