web-dev-qa-db-ja.com

Elixir-URLからファイル(画像)をダウンロードする

URLからファイル/画像をダウンロードするコードはElixirではどのように見えますか?

グーグル検索はエリクサー自体をダウンロードする方法を取り戻すようです。

23
BuddyJoe

ElixirのHTTPクライアントである httpoison をご覧ください。画像(またはファイル、それは無関係)を指すURLにGETリクエストを発行するだけです。

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

HTTPoison.get!/1HTTPoison.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)
47
whatyouhide

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を超えないことを示しました。一重引用符で囲まれた文字列に注意してください。このErlangライブラリにElixir文字列を渡すことはできません。

5
devstopfix

@whatyouhideが提供するダウンロード方法は機能しますが、欠点があります。

  • 応答全体がRAMにロードされ、その後でのみFile.write/1に送られます。高いメモリ消費を回避するには、非同期HTTPoison要求を選択する必要があります。
  • ダウンロードするファイルサイズの制限はありません。たとえば、ユーザー入力を処理してから、ユーザーが提供したファイルをダウンロードしようとすると、サーバーがダウンして1TBサイズのファイルをダウンロードする可能性があります。

これらの短所を回避するために ダウンロード エリクサーパッケージを作成しました。

それは素晴らしい構文を持ち、十分にテストされています。入力するだけです

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