OkHttpを使用してバイナリファイルをダウンロードする
1. 概要
このチュートリアルでは、OkHttpライブラリを使用してバイナリファイルをダウンロードする方法の実際的な例を示します。
2. Mavenの依存関係
まず、ベースライブラリokhttpの依存関係を追加します。
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>
次に、 OkHttpライブラリで実装されたモジュールの統合テストを作成する場合は、mockwebserverライブラリを使用できます。 このライブラリには、サーバーとその応答をモックするためのツールがあります。
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.9.1</version>
<scope>test</scope>
</dependency>
3. バイナリファイルのリクエスト
最初に、がファイルをダウンロードする場所からURL をパラメーターとして受け取り、がそのURLのHTTPリクエストを作成して実行するクラスを実装します。
クラスをテスト可能にするために、コンストラクターにOkHttpClientとライターを挿入します。
public class BinaryFileDownloader implements AutoCloseable {
private final OkHttpClient client;
private final BinaryFileWriter writer;
public BinaryFileDownloader(OkHttpClient client, BinaryFileWriter writer) {
this.client = client;
this.writer = writer;
}
}
次に、がURLからファイルをダウンロードするメソッドを実装します。
public long download(String url) throws IOException {
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
ResponseBody responseBody = response.body();
if (responseBody == null) {
throw new IllegalStateException("Response doesn't contain a file");
}
double length = Double.parseDouble(Objects.requireNonNull(response.header(CONTENT_LENGTH, "1")));
return writer.write(responseBody.byteStream(), length);
}
ファイルをダウンロードするプロセスには、4つのステップがあります。 URLを使用してリクエストを作成します。 リクエストを実行し、レスポンスを受け取ります。 応答の本文を取得するか、応答の場合は失敗します
4. ローカルファイルへの応答の書き込み
応答から受信したbytesをローカルファイルに書き込むために、 BinaryFileWriter クラスを実装します。このクラスは、がInputStreamとOutputStreamを入力として受け取り、 InputStreamからOutputStreamへ。
OutputStream がコンストラクターに挿入され、クラスをテストできるようになります。
public class BinaryFileWriter implements AutoCloseable {
private final OutputStream outputStream;
public BinaryFileWriter(OutputStream outputStream) {
this.outputStream = outputStream;
}
}
次に、コンテンツをInputStreamからOutputStreamにコピーするメソッドを実装します。 このメソッドは、最初にInputStreamをBufferedInputStreamでラップして、一度にさらにバイトを読み取ることができるようにします。 次に、InputStreamからbytesを一時的に格納するデータバッファを準備します。
最後に、バッファリングされたデータをWriteでOutputStreamに書き込みます。 InputStream に読み取るデータがある限り、これを行います。
public long write(InputStream inputStream) throws IOException {
try (BufferedInputStream input = new BufferedInputStream(inputStream)) {
byte[] dataBuffer = new byte[CHUNK_SIZE];
int readBytes;
long totalBytes = 0;
while ((readBytes = input.read(dataBuffer)) != -1) {
totalBytes += readBytes;
outputStream.write(dataBuffer, 0, readBytes);
}
return totalBytes;
}
}
5. ファイルのダウンロードの進行状況を取得する
場合によっては、ファイルのダウンロードの進行状況をユーザーに通知したいことがあります。
まず、機能インターフェイスを作成する必要があります。
public interface ProgressCallback {
void onProgress(double progress);
}
次に、BinaryFileWriterクラスで使用します。 これにより、すべてのステップで、ダウンローダーがこれまでに書き込んだ合計バイトが得られます。
まず、ProgressCallbackをフィールドとしてライタークラスに追加します。 次に、writeメソッドをが応答の長さをパラメーターとして受け取るように更新します。 これは、進捗状況を計算するのに役立ちます。
次に、これまでに記述された totalBytesとlength:から計算されたprogress を使用して、onProgressメソッドを呼び出します。
public class BinaryFileWriter implements AutoCloseable {
private final ProgressCallback progressCallback;
public long write(InputStream inputStream, double length) {
//...
progressCallback.onProgress(totalBytes / length * 100.0);
}
}
最後に、BinaryFileDownloaderクラスを合計応答長でwriteメソッドを呼び出すように更新します。 Content-Length ヘッダーから応答の長さを取得し、それをwriteメソッドに渡します。
public class BinaryFileDownloader {
public long download(String url) {
double length = getResponseLength(response);
return write(responseBody, length);
}
private double getResponseLength(Response response) {
return Double.parseDouble(Objects.requireNonNull(response.header(CONTENT_LENGTH, "1")));
}
}
6. 結論
この記事では、OkHttpライブラリを使用してURLからバイナリファイルをダウンロードする簡単で実用的な例を実装しました。
ファイルダウンロードアプリケーションの完全な実装と単体テストについては、GitHubでプロジェクトを確認してください。