Java InputStreamからStringへ

Java InputStreamからString

1. 概要

このチュートリアルでは、GuavaApache Commons IOライブラリ、およびプレーンJavaを使用して、how to convert an InputStream to a Stringを確認します。

この記事は、例としてここのthe “Java – Back to Basic” seriesの一部です。

2. グアバでの変換

Guavaの例から始めましょう–ByteSource機能を活用します。

@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));
}

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

  • firstInputStreamByteSourceでラップします–私が知る限り、これが最も簡単な方法です。

  • thenByteSourceをUTF8文字セットを持つCharSourceと見なします。

  • finallyCharSourceを使用して文字列として読み取ります。

simpler way of doing the conversion with 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 CommonsIOを使用した変換

CommonsIOライブラリを使用してこれを行う方法を見てみましょう。

ここでの重要な注意点は、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を閉じることによって閉じられることに注意してください。

これがJava7の例であり、Java 5の例ではない唯一の理由は、try-with-resourcesステートメントの使用です。これを標準のtry-finallyブロックwill compile just fine with 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));
}

この例では、最初にバイトブロックの読み取りと書き込みによってInputStreamByteArrayOutputStreamに変換され、次にOutputStreamがバイト配列に変換されます。これはStringの作成に使用されます。 )s。

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)を正しく読みやすい方法で実行するための最良の方法をコンパイルした後、そして非常に多くの大きく異なる答えと解決策を見た後、a clear and concise best practice for this is called forだと思います。

これらすべての例とコードスニペットcan be found on GitHubの実装–これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。