Переслать файл по http не считывая его целиком в оперативную память? (HttpClient)

Задача:

Есть большой файл на диске который мы хотим отправить на сервер по http используя наше приложение написанное на dotnet core.

Вопрос:

Подскажите как переслать файл с клиента на сервер не считывая его целиком в оперативную память?


Ответы (1 шт):

Автор решения: EvgeniyZ

А зачем вы засовываете файл в память, ведь есть же такая вещь, как Stream.

Самый простой пример использования будет таким:

  1. Открываем stream указанного файла, для файлов это FileStream. Нам нужно только чтение:

    using var fileSteam = File.Open("SomeFile", FileMode.Open);
    
  2. Далее для отправки нам нужно другой stream, который предназначен для отправки данных на сервер, зовется он StreamContent и принимает любой другой stream (будь то память, файл или что либо еще):

    using var content = new StreamContent(fileSteam);
    
  3. Отправляем данные на сервер. HttpClient имеет все необходимые методы отправки, выбирайте нужный. Я например буду отправлять на сервер transfer.sh, который принимает PUT запросы:

    var resp = await client.PutAsync("https://transfer.sh/myFile.exe", content);
    
  4. Ну остается нам прочитать ответ от сервера:

    var respContent = await resp.Content.ReadAsStringAsync();
    

Для теста я отправлю то, что было под рукой (драйвер для видеокарты), вес его ~500мб

Test

Как видите, потребление памяти у меня в районе 75мб, файл отправляется напрямую с диска. Если чуть подождать, то сервер отдает статус 200 (OK) и в ответ ссылку на файл, что показывает успешную загрузку файла на сервер.

Result


Если нам надо отправлять сразу несколько файлов, то для этого существует MultipartFormDataContent, который позволяет добавить в себя несколько данных для отправки, будет выглядеть все примерно так:

using var content = new MultipartFormDataContent
{
    streamContent1,
    streamContent2
};

content.Add(streamContent3);

var resp = await client.PostAsync("Адрес", content);

Я очень многое тут опустил, но думаю основная суть будет понятна.

→ Ссылка