Java InputStreamからStringへ

1概要

このチュートリアルでは、http://code.google.com/p/guava-libraries/[Guava](http://commons.apache.org)を使用して、 InputStream をString ** に変換する方法を調べます。/proper/commons-io/[Apache Commons IO]ライブラリ、およびプレーンJava。

この記事はリンクの一部です:/java-tutorial[The Java - Back to Basic]シリーズ、ここBaeldung。

2 Guava で変換する

グアバの例から始めましょう。

@Test
public void givenUsingGuava__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    ByteSource byteSource = new ByteSource() {
        @Override
        public InputStream openStream() throws IOException {
            return inputStream;
        }
    };

    String text = byteSource.asCharSource(Charsets.UTF__8).read();

    assertThat(text, equalTo(originalString));
}

手順を見ていきましょう。

  • 最初 - 私たちは InputStream ByteSource にラップします

知っている、これがそうする最も簡単な方法です そして** - 私たちは ByteSource をUTF8の CharSource として見ています。

文字セット

  • ついに - 文字列として読み込むために CharSource を使います。

Guava を使用して変換を行う 簡単な方法ですが、ストリームを明示的に閉じる必要があります。幸いなことに、try-with-resources構文を使ってそれを処理できます。

@Test
public void givenUsingGuavaAndJava7__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = null;
    try (final Reader reader = new InputStreamReader(inputStream)) {
        text = CharStreams.toString(reader);
    }

    assertThat(text, equalTo(originalString));
}

3 Apache Commons IO で変換する

それでは、Commons IOライブラリーを使ってこれを行う方法を見てみましょう。

ここで重要な注意点は - Guavaとは対照的に - これらの例はどちらも InputStream をクローズしないことです - これが私が個人的にはGuavaソリューションを好む理由です。

@Test
public void givenUsingCommonsIo__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = IOUtils.toString(inputStream, StandardCharsets.UTF__8.name());
    assertThat(text, equalTo(originalString));
}

変換を行うために StringWriter を使用することもできます。

@Test
public void givenUsingCommonsIoWithCopy__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    StringWriter writer = new StringWriter();
    String encoding = StandardCharsets.UTF__8.name();
    IOUtils.copy(inputStream, writer, encoding);

    assertThat(writer.toString(), equalTo(originalString));
}

4 Javaで変換する - InputStream

それでは、プレーンJavaを使用した低レベルのアプローチ、つまり InputStream と単純な StringBuilder を見てみましょう。

@Test
public void givenUsingJava5__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(DEFAULT__SIZE);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    StringBuilder textBuilder = new StringBuilder();
    try (Reader reader = new BufferedReader(new InputStreamReader
      (inputStream, Charset.forName(StandardCharsets.UTF__8.name())))) {
        int c = 0;
        while ((c = reader.read()) != -1) {
            textBuilder.append((char) c);
        }
    }
    assertEquals(textBuilder.toString(), originalString);
}

5 Javaと Scanner で変換する

次に、標準的なテキスト Scanner を使用して、単純なJavaの例を見てみましょう。

@Test
public void givenUsingJava7__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = null;
    try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF__8.name())) {
        text = scanner.useDelimiter("\\A").next();
    }

    assertThat(text, equalTo(originalString));
}

InputStream は、 Scanner のクローズによってクローズされます。

これがJava 7の例であり、Java 5の例ではない唯一の理由は、 try-with-resources ステートメントを使用することです - それを標準の try-finally block に変換すると、Java 5 でうまくコンパイルできます。

6. ByteArrayOutputStream を使用して変換する

最後に、今度は ByteArrayOutputStream クラスを使用した、別の単純なJavaの例を見てみましょう。

@Test
public final void givenUsingPlainJava__whenConvertingAnInputStreamToString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int nRead;
    byte[]data = new byte[1024];
    while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }

    buffer.flush();
    byte[]byteArray = buffer.toByteArray();

    String text = new String(byteArray, StandardCharsets.UTF__8);
    assertThat(text, equalTo(originalString));
}

この例では、最初にバイトブロックを読み書きすることによって InputStream ByteArrayOutputStream に変換され、次に OutputStream がバイト配列に変換されて、 String が作成されます。

7. java.nio で変換する

別の解決策は InputStream の内容をファイルにコピーしてからこれを__Stringに変換することです。

@Test
public final void givenUsingTempFile__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(DEFAULT__SIZE);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    Path tempFile = Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp");
    Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE__EXISTING);
    String result = new String(Files.readAllBytes(tempFile));

    assertThat(result, equalTo(originalString));
}

ここでは、 java.nio.file.Files クラスを使用して一時ファイルを作成し、 InputStream の内容をファイルにコピーします。

次に、同じクラスを使用して、 readAllBytes() メソッドを使用してファイルの内容を String に変換します。

8結論

InputStreamからStringへの簡単な変換を行うための最善の方法を正しく読みやすい方法でコンパイルした後、そして非常に多くの極端に異なる回答や解決策を見た後で、 これに対する明確で簡潔なベストプラクティスが と呼ばれると思います。

これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/core-java-io[GitHub]** にあります。これはMavenベースのプロジェクトなので、インポートしてそのまま実行するのは簡単なはずです。

前の投稿:Javaオプション - orElse()vs orElseGet()
次の投稿:アントコロニーの最適化