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á.