本稿では、URLからファイルを非同期でダウンロードする方法について解説します。
- ファイルのダウンロードを自動化したい
- 初期処理等のため、プログラム上でファイルをダウンロードする必要がある
- 複数ファイルを並列でダウンロードしたい
Javaの標準ライブラリによる実装方法やApache HttpComponents、AsyncHttpClient などの外部ライブラリを用いた実装方法についていくつかサンプルを掲載します。
非同期を考慮しないシンプルな実装方法についてはこちらを参照ください。
Java標準ライブラリで行う方法
Executorフレームワークは、スレッドプールを利用した並列処理実行を行えるようJava 1.5 で導入されたもので、WorkerThreadパターンをシンプルに実装することができます。
以下のサンプルではファイルをダウンロードするタスクをExecutorServiceに送信して、スレッドプール内で実行しています。ここでは戻り値を気にしていませんが、Futureクラスを得るとタスクを追跡することができます。サンプルでは完了までの時間を考慮していませんが、ダウンロードにある程度時間がかかる見込みがあれば、CompletableFutureを使用してすべてのタスクの完了を待ってから終了しましょう。
Java
Apache HttpComponents を使う方法
org.apache.http パッケージを使用してファイルをダウンロードします。
GETやPOSTなどHTTPメソッドを簡単に使い分けできます。また、FutureCallbackではデータ取得完了時、失敗時、キャンセル時の挙動を制御できます。サンプルではリクエストが完了した時にレスポンスを読み取ってファイルに保存しています。
セットアップ
Mavenを使用する場合は、pom.xmlに以下の依存性を追加してください。
pom.xml
特にプロジェクト管理ツールを使わない場合はより公式よりzipをダウンロードして、プロジェクトにjarを追加してください。
ソースコード
Java
補足
ホストが見つからない場合もファイルが見つからない場合も、FutureCallback#failedが呼ばれます。
AsyncHttpClient を使う方法
AsyncHttpClientライブラリにより、HTTP要求を簡単に実行しHTTP応答を非同期的に処理できます。コールバックを定義することで完了時にファイルを保存するよう制御できます。
以下のサンプルでは、CompletableFutureを使用して、すべてのタスクが完了してからクライアントをクローズするようにしています。
セットアップ
Mavenを使用する場合は、pom.xmlに以下の依存性を追加してください。
pom.xml
特にプロジェクト管理ツールを使わない場合はMavenのCentralリポジトリよりjarをダウンロードしてください。
async-http-client-2.10.4.jar
ソースコード
Java
注意
ファイルが存在しない場合でも、接続先のサーバがステータスコード404を返してくれるような場合はonCompleteが呼ばれます。処理の中で適当に扱う必要があります。
ホスト自体が見つからない場合や応答がない場合はonCompleteは呼ばれません。
また、応答なしを考慮してクライアント生成時にタイムアウトを設定したほうがよいでしょう。