1. 概要

このクイックチュートリアルでは、JavaInputStreamをJavaOutputStreamに書き込む方法を学習します。 まず、Java8およびJava9のコア機能を使用します。 次に、GuavaApacheCommonsIOライブラリの2つの外部ライブラリを見ていきます。

Java 9、Guava、およびApache Commons IOによって提供されるユーティリティメソッドは、ストリームをフラッシュまたはクローズしません。 したがって、try-with-resourcesまたはfinallyブロックを使用してこれらのリソースを管理する必要があります。

2. Java8の使用

まず、バニラJavaを使用して、コンテンツをInputStreamからOutputStreamにコピーする簡単なメソッドを作成することから始めます。

void copy(InputStream source, OutputStream target) throws IOException {
    byte[] buf = new byte[8192];
    int length;
    while ((length = source.read(buf)) > 0) {
        target.write(buf, 0, length);
    }
}

このコードは非常に単純です—単にいくつかのバイトを読み込んでから、それらを書き出すだけです。

3. Java9の使用

Java 9は、このタスク用のユーティリティメソッドInputStream.transferTo()を提供します

transferTo()メソッドをどのように使用するかを見てみましょう。

@Test
public void givenUsingJavaNine_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
    String initialString = "Hello World!";

    try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
         ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
        inputStream.transferTo(targetStream);

        assertEquals(initialString, new String(targetStream.toByteArray()));
    }
}

ファイルストリームを操作する場合、 transferTo()メソッドよりもFiles.copy()を使用する方が効率的であることに注意してください。

4. グアバの使用

次に、GuavaのユーティリティメソッドByteStreams.copy()どのように使用するかを見てみましょう。

pom.xmlguava依存関係を含める必要があります。

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

ByteStreamsを使用してデータをコピーする方法を示す簡単なテストケースを作成しましょう。

@Test
public void givenUsingGuava_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
    String initialString = "Hello World!";

    try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
         ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
        ByteStreams.copy(inputStream, targetStream);

        assertEquals(initialString, new String(targetStream.toByteArray()));
    }
}

5. CommonsIOの使用

最後に、このタスクでCommons IO IOUtils.copy()メソッドを使用する方法を見てみましょう。

もちろん、commons-io依存関係をpom.xmlに追加する必要があります。

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

IOUtils を使用して、入力ストリームから出力ストリームにデータをコピーする簡単なテストケースを作成しましょう。

@Test
public void givenUsingCommonsIO_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
    String initialString = "Hello World!";

    try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
         ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
        IOUtils.copy(inputStream, targetStream);

        assertEquals(initialString, new String(targetStream.toByteArray()));
    }
}

注:Commons IOは、InputStreamおよびOutputStreamを操作するための追加のメソッドを提供します。 2 GB以上のデータをコピーする必要がある場合は、IOUtils.copyLarge()を使用する必要があります。

6. 結論

この記事では、InputStreamからOutputStreamにデータをコピーする簡単な方法について説明しました。

これらの例の実装は、GitHubから入手できます。