Elixir - 从 URL 下载文件(图片)
Elixir - Download a File (Image) from a URL
从 URL 下载 file/image 的代码在 Elixir 中是什么样子的?
Google 搜索似乎带回了如何下载 Elixir 本身。
看看 httpoison,Elixir 的 HTTP 客户端。您可以向指向图像(或文件,无关紧要)的 url 发出 GET
请求:
%HTTPoison.Response{body: body} = HTTPoison.get!("http://example.com/img.png")
HTTPoison.get!/1
returns 一个 HTTPoison.Response
结构;我匹配该结构以获得响应的主体。现在 body
变量包含图像数据(只是一个二进制文件);您可以将其写入文件:
File.write!("/tmp/image.png", body)
好了 :).
即使不使用 httppoison,这显然也是可能的,但是您将不得不处理原始 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)
@whatyouhide 提供的下载方法有效但有缺点:
- 整个响应正在加载到 RAM,然后才转到
File.write/1
。你必须选择异步 HTTPoison 请求来避免高内存消耗。
- 下载的文件大小没有限制。如果你处理,比如说,用户输入,然后你试图下载用户提供的任何文件,你的服务器可能会因为下载一个 1TB 大小的文件而停机。
我创建了 download 长生不老药包来绕过这些缺点。
它的语法很好并且经过了良好的测试。只需输入
Download.from(url, [path: "/where/to/save", max_file_size: integer_in_bytes])
使用 httpc 将 URL 直接流式传输到文件:
:inets.start()
:ssl.start()
{:ok, :saved_to_file} = :httpc.request(:get, {'https://elixir-lang.org/images/logo/logo.png', []}, [], [stream: '/tmp/elixir'])
我下载了一个 183MB 的文件,观察者显示内存使用从未超过 25MB。注意单引号字符串!我们不能将 Elixir 字符串传递给这个 Erlang 库。
从 URL 下载 file/image 的代码在 Elixir 中是什么样子的?
Google 搜索似乎带回了如何下载 Elixir 本身。
看看 httpoison,Elixir 的 HTTP 客户端。您可以向指向图像(或文件,无关紧要)的 url 发出 GET
请求:
%HTTPoison.Response{body: body} = HTTPoison.get!("http://example.com/img.png")
HTTPoison.get!/1
returns 一个 HTTPoison.Response
结构;我匹配该结构以获得响应的主体。现在 body
变量包含图像数据(只是一个二进制文件);您可以将其写入文件:
File.write!("/tmp/image.png", body)
好了 :).
即使不使用 httppoison,这显然也是可能的,但是您将不得不处理原始 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)
@whatyouhide 提供的下载方法有效但有缺点:
- 整个响应正在加载到 RAM,然后才转到
File.write/1
。你必须选择异步 HTTPoison 请求来避免高内存消耗。 - 下载的文件大小没有限制。如果你处理,比如说,用户输入,然后你试图下载用户提供的任何文件,你的服务器可能会因为下载一个 1TB 大小的文件而停机。
我创建了 download 长生不老药包来绕过这些缺点。
它的语法很好并且经过了良好的测试。只需输入
Download.from(url, [path: "/where/to/save", max_file_size: integer_in_bytes])
使用 httpc 将 URL 直接流式传输到文件:
:inets.start()
:ssl.start()
{:ok, :saved_to_file} = :httpc.request(:get, {'https://elixir-lang.org/images/logo/logo.png', []}, [], [stream: '/tmp/elixir'])
我下载了一个 183MB 的文件,观察者显示内存使用从未超过 25MB。注意单引号字符串!我们不能将 Elixir 字符串传递给这个 Erlang 库。