Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this short tutorial, we’ll shed light on how to convert a PrintStream to a String in Java.

We’ll start by using core Java methods. Then, we will see how to achieve the same objective using external libraries such as Apache Commons IO.

2. What Is a PrintStream

In Java, PrintStream is an output stream that provides a convenient way to print and format data. It comes with a set of methods for printing and formatting different types of data, such as println() and printf().

Unlike other output streams, it never throws an IOException. However, in case of errors, it sets a flag that can be tested via the checkError() method.

Now that we know what a PrintStream is, let’s see how to convert it into a string.

3. Using ByteArrayOutputStream

In short, ByteArrayOutputStream is an output stream in which the data is written into a byte array.

Typically, we can use it to capture the output of the PrintStream, and then convert the captured bytes to a string. So, let’s see in action:

public static String usingByteArrayOutputStreamClass(String input) throws IOException {
    if (input == null) {
        return null;
    }

    String output;
    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(outputStream)) {
        printStream.print(input);

        output = outputStream.toString();
    }

    return output;
}

As we can see, we created a PrintStream object with ByteArrayOutputStream passed into the constructor.

Then, we wrote the input string to PrintStream using the print() method.

Finally, we converted the input to a String object using the toString() method of the ByteArrayOutputStream class.

Now, let’s confirm this using a test case:

@Test
public void whenUsingByteArrayOutputStreamClass_thenConvert() throws IOException {
    assertEquals("test", PrintStreamToStringUtil.usingByteArrayOutputStreamClass("test"));
    assertEquals("", PrintStreamToStringUtil.usingByteArrayOutputStreamClass(""));
    assertNull(PrintStreamToStringUtil.usingByteArrayOutputStreamClass(null));
}

As shown above, our method does its job of converting a PrintStream into a string.

4. Using Custom Output Stream

Another solution would be using a custom implementation of the OutputStream class.

Basically, OutputStream is the superclass for all classes representing an output stream of bytes, including ByteArrayOutputStream.

First, let’s consider the CustomOutputStream static inner class:

private static class CustomOutputStream extends OutputStream {

    private StringBuilder string = new StringBuilder();

    @Override
    public void write(int b) throws IOException {
        this.string.append((char) b);
    }

    @Override
    public String toString() {
        return this.string.toString();
    }
}

Here, we used a StringBuilder instance to write the given data byte by byte. Furthermore, we overrode the toString() method to get the string’s representation of the StringBuilder object.

Next, let’s reuse the same example from the previous section. However, we will use our custom implementation instead of ByteArrayOutputStream:

public static String usingCustomOutputStream(String input) throws IOException {
    if (input == null) {
        return null;
    }

    String output;
    try (CustomOutputStream outputStream = new CustomOutputStream(); PrintStream printStream = new PrintStream(outputStream)) {
        printStream.print(input);

        output = outputStream.toString();
    }

    return output;
}

Now, let’s add another test case to confirm that everything works as expected:

@Test
public void whenCustomOutputStream_thenConvert() throws IOException {
    assertEquals("world", PrintStreamToStringUtil.usingCustomOutputStream("world"));
    assertEquals("", PrintStreamToStringUtil.usingCustomOutputStream(""));
    assertNull(PrintStreamToStringUtil.usingCustomOutputStream(null));
}

5. Using Apache Commons IO

Alternatively, we can use the Apache Commons IO library to achieve the same objective.

First, let’s add the Apache Commons IO dependency to our pom.xml:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.15.1</version>
</dependency>

Apache Commons IO provides its own version of ByteArrayOutputStream. This class comes with the toByteArray() method to retrieve the data as an array of bytes.

Let’s see it in practice:

public static String usingApacheCommonsIO(String input) {
    if (input == null) {
        return null;
    }

    org.apache.commons.io.output.ByteArrayOutputStream outputStream = new org.apache.commons.io.output.ByteArrayOutputStream();
    try (PrintStream printStream = new PrintStream(outputStream)) {
        printStream.print(input);
    }

    return new String(outputStream.toByteArray());
}

In a nutshell, we used toByteArray() to get the byte array from the output stream. Then, we passed the returned array to the String constructor.

An important caveat here is that, as opposed to Java, we don’t need to close the ByteArrayOutputStream.

This solution also works fine, as demonstrated in the unit test:

@Test
public void whenUsingApacheCommonsIO_thenConvert() {
    assertEquals("hello", PrintStreamToStringUtil.usingApacheCommonsIO("hello"));
    assertEquals("", PrintStreamToStringUtil.usingApacheCommonsIO(""));
    assertNull(PrintStreamToStringUtil.usingApacheCommonsIO(null));
}

6. Conclusion

In this article, we learned how to convert a PrintStream to a String.

Along the way, we explained how to do it using core Java methods. Then, we illustrated how to use external libraries such as Apache Commons IO.

As always, the code used in this article can be found over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.