Reputation: 71131
What does the code to download a file/image from a URL look like in Elixir?
Google searches seem to bring back how to download Elixir itself.
Upvotes: 31
Views: 16048
Reputation: 6808
To stream the URL directly to a file with httpc:
:inets.start()
:ssl.start()
{:ok, :saved_to_file} = :httpc.request(:get, {'https://elixir-lang.org/images/logo/logo.png', []}, [], [stream: '/tmp/elixir'])
I downloaded a 183MB file and the observer showed that memory use never exceeded 25MB. Note the single quoted strings! We cannot pass Elixir strings to this Erlang library.
Upvotes: 18
Reputation: 15206
Download method provided by @whatyouhide works but have drawbacks:
File.write/1
. You have to choose async HTTPoison request to escape high memory consumption.I created download elixir package to bypass these cons.
It has nice syntax and well-tested. Just type
Download.from(url, [path: "/where/to/save", max_file_size: integer_in_bytes])
Upvotes: 10
Reputation: 16781
Have a look at httpoison, an HTTP client for Elixir. You can just issue a GET
request to the url pointing to the image (or file, it's irrelevant):
%HTTPoison.Response{body: body} = HTTPoison.get!("http://example.com/img.png")
HTTPoison.get!/1
returns an HTTPoison.Response
struct; I matched on that struct in order to get the body of the response. Now the body
variables contains the image data (which is just a binary); you can write it to a file:
File.write!("/tmp/image.png", body)
and there you go :).
This is obviously possible even without using httpoison, but you would have to deal with raw TCP connections (look at the gen_tcp
Erlang module), parsing of the HTTP response and a bunch of stuff you usually don't want to do manually.
Whoops, forgot to mention the httpc
Erlang module (included in the stdlib!), which makes this very simple without the need for a dependency like 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)
Upvotes: 55