Подтвердить что ты не робот

Как загрузить большой файл (через HTTP) в .NET?

Мне нужно загрузить большой файл (2 GB) через HTTP в консольном приложении С#. Проблема в том, что после примерно 1,2 GB в приложении заканчивается память.

Вот код, который я использую:

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

Как вы можете видеть... Я читаю файл непосредственно в памяти. Я уверен, что смогу это решить, если я прочитаю данные из HTTP в кусках и напишу их в файл на диске.

Как я могу это сделать?

4b9b3361

Ответ 1

Если вы используете WebClient.DownloadFile, вы можете сохранить его непосредственно в файл.

Ответ 2

Класс 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);
            }
        }
    }
}

Обратите внимание, что если WebClient.DownloadFile работает, я бы назвал это лучшим решением. Я написал выше, прежде чем был отправлен ответ "DownloadFile". Я также писал это слишком рано утром, поэтому может потребоваться зерно соли (и тестирование).

Ответ 3

Вам нужно получить поток ответов, а затем прочитать в блоках, записывая каждый блок в файл, чтобы позволить повторно использовать память.

Как вы его написали, весь ответ, все 2GB, должен быть в памяти. Даже на 64-битной системе, которая достигнет предела 2 ГБ для одного объекта .NET.


Обновление: проще. Получите WebClient, чтобы выполнить эту работу для вас: с помощью метода DownloadFile, который поместит данные непосредственно в файл.

Ответ 4

я бы использовал что-то вроде this

Ответ 5

WebClient.OpenRead возвращает поток, просто используйте Read для циклического преобразования содержимого, поэтому данные не буферизуются в памяти, а могут быть записаны в виде блоков в файл.