如何在.NET中下载大文件(通过HTTP)?

Nic*_*ght 24 .net c# http large-files

我需要在C#控制台应用程序中通过HTTP 下载文件(2 GB).问题是,在大约1.2 GB之后,应用程序内存不足.

这是我正在使用的代码:

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

正如你所看到的......我正在将文件直接读入内存.我很确定如果我要从块中读取数据并将其写入磁盘上的文件,我可以解决这个问题.

我怎么能这样做?

Ale*_*eck 38

如果使用WebClient.DownloadFile,则可以将其直接保存到文件中.


Joh*_*ers 33

WebClient类是简化方案的类.一旦你通过简单的场景(你有),你将不得不退回一点并使用WebRequest.

使用WebRequest,您将可以访问响应流,并且您将能够遍历它,读取一点并写一点,直到您完成为止.


例:

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果WebClient.DownloadFile工作,那么我称之为最佳解决方案.在发布"DownloadFile"答案之前,我写了上述内容.我也是在早上太早写的,所以可能需要一些盐(和测试).


Ric*_*ard 9

您需要获取响应流,然后读取块,将每个块写入文件以允许重用内存.

正如你所写,整个响应,所有2GB,需要在内存中.即使在64位系统上,单个.NET对象也会达到2GB的限制.


更新:更容易的选择.获取WebClient为您做的工作:与它的DownloadFile方法,这将直接把数据放到一个文件中.