convert-input-stream-to-string
Java InputStream to String
1. Overview
In this tutorial we’ll look at how to convert an InputStream to a String, using Guava, the Apache Commons IO library, and plain Java.
This article is part of the “Java – Back to Basic” series here on Baeldung.
2. Converting with 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));
}
Let’s go over the steps:
-
first – we wrap our InputStream a ByteSource – and as far as I’m aware, this is the easiest way to do so
-
then – we view our ByteSource as a CharSource with a UTF8 charset.
-
finally – we use the CharSource to read it as a String.
A simpler way of doing the conversion with Guava, but the stream needs to be explicitly closed; luckily, we can simply use the try-with-resources syntax to take care of that:
@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. Converting with Apache Commons IO
An important caveat here is that – as opposed to Guava – neither of these examples will close the InputStream – which is why I personally prefer the Guava solution.
@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));
}
We can also use a StringWriter to do the conversion:
@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. Converting with Java – InputStream
Let’s look now at a lower level approach using plain Java – an InputStream and a simple 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. Converting with Java and a 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));
}
Note that the InputStream is going to be closed by the closing of the Scanner.
The only reason this is a Java 7 example, and not a Java 5 one is the use of the try-with-resources statement – turning that into a standard try-finally block will compile just fine with Java 5.
6. Converting Using 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));
}
In this example, first the InputStream is converted to a ByteArrayOutputStream by reading and writing byte blocks, then the OutputStream is transformed to a byte array, which is used to create a String.
7. Converting with java.nio
Another solution is to copy the content of the InputStream to a file, then convert this to a 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));
}
Here, we’re using the java.nio.file.Files class to create a temporary file, as well as copy the content of the InputStream to the file. Then, the same class is used to convert the file content to a String with the readAllBytes() method.
8. Conclusion
After compiling the best way to do the simple conversion – InputStream to String – in a correct and readable way – and after seeing so many wildly different answers and solutions – I think that a clear and concise best practice for this is called for.
The implementation of all these examples and code snippets can be found on GitHub – this is a Maven-based project, so it should be easy to import and run as it is.