Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I download a large file (via HTTP) in .NET?

I need to download a large file (2 GB) over HTTP in a C# console application. Problem is, after about 1.2 GB, the application runs out of memory.

Here's the code I'm using:

WebClient request = new WebClient();
request.Credentials = new NetworkCredential(username, password);
byte[] fileData = request.DownloadData(baseURL + fName);

As you can see... I'm reading the file directly into memory. I'm pretty sure I could solve this if I were to read the data back from HTTP in chunks and write it to a file on disk.

How could I do this?

like image 743
Nick Cartwright Avatar asked Jul 03 '09 09:07

Nick Cartwright


People also ask

How do I download a file from HTTP?

In general, downloading a file from an HTTP server terminal via HTTP GET consists of the following steps: Make an HTTP GET request to send to the HTTP server. Send an HTTP request and receive an HTTP response from the HTTP server. Save the contents of the HTTP response file to a local file.

How can I download large files faster on the Internet?

For very large size downloads (more than 2GB), we recommend that you use a Download Manager to do the downloading. This can make your download more stable and faster, reducing the risk of a corrupted file. Simply save the download file to your local drive.

How does HTTP file download work?

Hypertext Transfer Protocol (HTTP) downloads use the same protocol as browsing websites to send the file data. It is the most popular way to download files from the internet. All web browsers use this to download files directly. HTTP does not support pausing or resuming failed downloads natively.


2 Answers

If you use WebClient.DownloadFile you could save it directly into a file.

like image 153
Alex Peck Avatar answered Sep 21 '22 17:09

Alex Peck


The WebClient class is the one for simplified scenarios. Once you get past simple scenarios (and you have), you'll have to fall back a bit and use WebRequest.

With WebRequest, you'll have access to the response stream, and you'll be able to loop over it, reading a bit and writing a bit, until you're done.

From the Microsoft documentation:

We don't recommend that you use WebRequest or its derived classes for new development. Instead, use the System.Net.Http.HttpClient class.

Source: docs.microsoft.com/WebRequest


Example:

public void MyDownloadFile(Uri url, string outputFilePath)
{
    const int BUFFER_SIZE = 16 * 1024;
    using (var outputFileStream = File.Create(outputFilePath, BUFFER_SIZE))
    {
        var req = WebRequest.Create(url);
        using (var response = req.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {
                var buffer = new byte[BUFFER_SIZE];
                int bytesRead;
                do
                {
                    bytesRead = responseStream.Read(buffer, 0, BUFFER_SIZE);
                    outputFileStream.Write(buffer, 0, bytesRead);
                } while (bytesRead > 0);
            }
        }
    }
}

Note that if WebClient.DownloadFile works, then I'd call it the best solution. I wrote the above before the "DownloadFile" answer was posted. I also wrote it way too early in the morning, so a grain of salt (and testing) may be required.

like image 30
John Saunders Avatar answered Sep 18 '22 17:09

John Saunders