Java InputStream para String

Java InputStream para String

*1. Visão geral *

Neste tutorial, veremos* como converter um InputStream em uma String *, usando Guava, o https://commons.apache.org/apropriada/commons-io/biblioteca [Apache Commons IO] e Java comum.

Este artigo é parte do link:/java-tutorial [a série “Java - Back to Basic”] aqui no Baeldung.

*2. Convertendo com goiaba *

Vamos começar com um exemplo do Guava - aproveitando a funcionalidade 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));
}

Vamos passar pelas etapas:

  • primeiro - agrupamos nosso InputStream a ByteSource - e, tanto quanto sei, esta é a maneira mais fácil de fazer isso

  • then - vemos nosso ByteSource como um CharSource com um conjunto de caracteres UTF8.

  • finalmente - usamos o CharSource para lê-lo como uma String.

Uma maneira mais simples de fazer a conversão com o Guava , mas o fluxo precisa ser explicitamente fechado; felizmente, podemos simplesmente usar a sintaxe try-with-resources para cuidar disso:

@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. Convertendo com o Apache Commons IO *

Vamos agora ver como fazer isso com a biblioteca Commons IO.

Uma ressalva importante aqui é que - ao contrário do Guava - nenhum desses exemplos fecha o InputStream - e é por isso que eu pessoalmente prefiro a solução do 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));
}

Também podemos usar um StringWriter para fazer a conversão:

@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. Convertendo com Java - InputStream *

Vejamos agora uma abordagem de nível inferior usando Java simples - um InputStream e um simples 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. Convertendo com Java e um Scanner *

A seguir - vejamos um exemplo simples de Java - usando um texto padrão Scanner:

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

Observe que o InputStream será fechado pelo fechamento do Scanner.

A única razão pela qual este é um exemplo do Java 7, e não o do Java 5, é o uso da instrução try-with-resources - transformar isso em um bloco padrão try-finally* compilará muito bem com o Java 5 *.

*6. Convertendo usando ByteArrayOutputStream *

Por fim, vejamos outro exemplo simples de Java, desta vez usando a classe ByteArrayOutputStream:

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

Neste exemplo, primeiro o InputStream é convertido em um ByteArrayOutputStream lendo e gravando blocos de bytes, depois o OutputStream é transformado em uma matriz de bytes, usada para criar um String.

===* 7. Convertendo com java.nio *

Outra solução é copiar o conteúdo do InputStream para um arquivo e convertê-lo em um _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));
}

Aqui, estamos usando a classe java.nio.file.Files para criar um arquivo temporário, bem como copiar o conteúdo da InputStream para o arquivo. Em seguida, a mesma classe é usada para converter o conteúdo do arquivo em um String com o método _readAllBytes () _.

===* 8. Conclusão *

Depois de compilar a melhor maneira de fazer a conversão simples - InputStream para String - de maneira correta e legível - e depois de ver tantas respostas e soluções totalmente diferentes - acho que* é uma prática recomendada clara e concisa para isso *.

A implementação de todos esses exemplos e trechos de código * pode ser encontrada em https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-io[GitHubunette* - este é um Maven baseado em projeto, portanto, deve ser fácil importar e executar como está.