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

Elixir - загрузить файл (изображение) из URL-адреса

Что делает код для загрузки файла/изображения из URL-адреса в Elixir?

Поиски Google, похоже, возвращают, как загрузить сам эликсир.

4b9b3361

Ответ 1

Посмотрите httpoison, клиент HTTP для Elixir. Вы можете просто отправить запрос GET на url, указывающий на изображение (или файл, это не имеет значения):

%HTTPoison.Response{body: body} = HTTPoison.get!("http://example.com/img.png")

HTTPoison.get!/1 возвращает структуру HTTPoison.Response; Я подобрал эту структуру, чтобы получить тело ответа. Теперь переменные body содержат данные изображения (которые являются только двоичными); вы можете записать его в файл:

File.write!("/tmp/image.png", body)

и там вы идете:).

Это, очевидно, возможно даже без использования httpoison, но вам придется иметь дело с необработанными TCP-соединениями (посмотрите gen_tcp модуль Erlang), разбор HTTP-ответа и куча вещей, которые вы обычно не хотите делать вручную.

Упс, забыл упомянуть модуль httpc Erlang (входит в stdlib!), что делает это очень простым без необходимости в зависимости от HTTPoison:

Application.ensure_all_started :inets

{:ok, resp} = :httpc.request(:get, {'http://example.com/my_image.jpg', []}, [], [body_format: :binary])
{{_, 200, 'OK'}, _headers, body} = resp

File.write!("/tmp/my_image.jpg", body)

Ответ 2

Метод загрузки, предоставляемый @whatyouhide, работает, но имеет недостатки:

  • Весь ответ загружается в ОЗУ и только после этого идет в File.write/1. Вы должны выбрать асинхронный HTTPoison запрос, чтобы избежать высокого потребления памяти.
  • Нет ограничений на размер файла для скачивания. Если вы обрабатываете, скажем, пользовательский ввод, а затем пытаетесь загрузить любой предоставленный пользователем файл, ваш сервер может отключиться для загрузки файла размером 1 ТБ.

Я создал загрузочный пакет эликсира, чтобы обойти эти минусы.

Он имеет хороший синтаксис и хорошо проверен. Просто введите

Download.from(url, [path: "/where/to/save", max_file_size: integer_in_bytes])

Ответ 3

Для потоковой передачи URL-адреса непосредственно в файл с httpc:

:inets.start()
:ssl.start() 

{:ok, :saved_to_file} = :httpc.request(:get, {'https://elixir-lang.org/images/logo/logo.png', []}, [], [stream: '/tmp/elixir'])                     

Я загрузил файл размером 183 МБ, и наблюдатель показал, что использование памяти никогда не превышало 25 МБ.