The Master Class of "Learn Spring Security" is live:

>> CHECK OUT THE COURSE

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. Convert with Guava

Let’s start with a Guava example – leveraging the ByteSource functionality:

@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 in an 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. Convert with Apache Commons IO

Let’s now look at how to do this with the Commons IO library.

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. Convert 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. Convert with Java and a Scanner

Finally – let’s now look at a plain Java example – using a standard text 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. 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 in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I just released the Master Class of "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

  • Greg Brown

    Why not just use an InputStreamReader and a StringBuilder? No 3rd-party libraries required.

    @Test
    public void testInputStreamToString() throws IOException {
    String originalString = “abcdefghijklmnop”;
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    StringBuilder textBuilder = new StringBuilder();
    try (InputStreamReader inputStreamReader = new InputStreamReader(inputStream,
    Charset.forName(“UTF-8”))) {
    int c = 0;
    while ((c = inputStreamReader.read()) != -1) {
    textBuilder.append((char)c);
    }
    }

    Assert.assertEquals(textBuilder.toString(), originalString);
    }

    • Hey Greg, I did consider including a Java 5 style solution in the article – the only reason I didn’t at the time was that I didn’t like the idea of the explicit character by character approach for large Strings. I tested it out and it is indeed twice as slow as all the other options (just a quick empirical test). However, seeing how these micro-benchmarks aren’t all that usefull, I think you’re right – and I will include it in the article.
      Thanks for the feedback and the code sample – it’s not every day that someone actually pastes in a working one 🙂
      Cheers,
      Eugen.

      • Greg Brown

        Hi Eugen,
        That example was actually written for Java 7 (like your example, it uses try-with-resources). Of course, it could be easily modified to work with Java 5.
        I suspect that the other implementations use buffering to help make things faster. My example could probably be similarly optimized (maybe by using a BufferedReader).
        Greg

        • Yeah, I noticed the try with resources – and you’re right, as my other example, it can be easily modified to work with Java 5. As for the speed, I’m sure it can be optimized – but doing that early is probably not necessary, so I’m not focusing to much on that. Wrapping the raw reader in a BufferedReader may however be worth it.
          Cheers,
          Eugen.

  • Greg Brown

    Sorry about the formatting – Disqus appears to have ignored my spacing.

  • @baeldung:disqus All the examples are very good. I am usually in favor of code that relies as much as possible on functionalities coming straight from the Java standard library. Pointing out about try-with-resources is also nice. I don’t think that many developers are fully aware of it, and perhaps, it’s worth giving it attention in another “back to basics” post. Keep up the good work!

    • That’s certainly a good topic to explore – thanks for the suggestion. Adding it to my content calendar. Cheers,
      Eugen.

  • Manoj

    I’ll use ByteArrayOutputStream and write blocks to it, then create string from byte array. It’s the fastest method I know.