Elixir - загрузить файл (изображение) из URL-адреса
Что делает код для загрузки файла/изображения из URL-адреса в Elixir?
Поиски Google, похоже, возвращают, как загрузить сам эликсир.
Ответы
Ответ 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 МБ.