129

I have a function that takes an object of a certain type, and a PrintStream to which to print, and outputs a representation of that object. How can I capture this function's output in a String? Specifically, I want to use it as in a toString method.

Nick Heiner
  • 119,074
  • 188
  • 476
  • 699

6 Answers6

213

Use a ByteArrayOutputStream as a buffer:

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;

    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    final String utf8 = StandardCharsets.UTF_8.name();
    try (PrintStream ps = new PrintStream(baos, true, utf8)) {
        yourFunction(object, ps);
    }
    String data = baos.toString(utf8);
ChssPly76
  • 99,456
  • 24
  • 206
  • 195
  • 12
    Don't forget to close the PrintStream to free all resources. – tobr Jun 20 '12 at 09:11
  • 6
    Use `new String(baos.toByteArray(), java.nio.charset.StandardCharsets.UTF_8);` available since **1.7**, it doesn't throw – earcam Feb 15 '16 at 22:57
  • 2
    @tobr certainly a good rule of thumb, but [`ByteArrayOutputStream.close()`](https://docs.oracle.com/javase/8/docs/api/java/io/ByteArrayOutputStream.html#close--) "*has no effect*", as there are no resources to free besides the backing array which will be dealt with by the garbage collector. – dimo414 Jun 05 '16 at 05:03
  • `ByteArrayOutputStream` has `toString(String charsetName)`, but only accept String argument. Also note that ByteArrayOutputStream is **synchronized**, which probably is not desirable – don't panic Nov 29 '18 at 09:03
  • Both the `PrintStream` constructor and the `baos.toString` method now support the `Charset` objects directly, so there is no more need to convert `UTF_8` to `UTF_8.name()` first... I recommend adding `import static java.nio.charset.StandardCharsets.UTF_8;` so you can use `UTF_8` directly as a value. – neXus Apr 07 '23 at 08:50
36

You can construct a PrintStream with a ByteArrayOutputStream passed into the constructor which you can later use to grab the text written to the PrintStream.

ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
...
String output = os.toString("UTF8");
Asaph
  • 159,146
  • 25
  • 197
  • 199
12

Why don't you use a StringWriter with a PrintWriter?

StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
out.println("Hello World!");
String output = writer.toString();
Clebert Suconic
  • 5,353
  • 2
  • 22
  • 35
  • Apart from top rated answer this one doesn't bother you with charsetName. – andrey Mar 11 '12 at 13:19
  • 7
    This won't work. You cannot pass the PrintWriter into a function which only takes a PrintStream as argument, which was what the question was about. – Alderath Jul 06 '12 at 11:29
  • 1
    I gave it as a suggestion on replacing the PrintStream. It's usually a good choice. If you must use a PrintStream then this i definitely not a choice. (I'm not sure why someone would vote -1 on this.. it still technically a viable option in most cases :) ) – Clebert Suconic Apr 11 '13 at 21:39
7

A unification of previous answers, this answer works with Java 1.7 and after. Also, I added code to close the Streams.

final Charset charset = StandardCharsets.UTF_8;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos, true, charset.name());
yourFunction(object, ps);
String content = new String(baos.toByteArray(), charset);
ps.close();
baos.close();
Kaelan Dawnstar
  • 141
  • 2
  • 7
2

Maybe this question might help you: Get an OutputStream into a String

Subclass OutputStream and wrap it in PrintStream

Community
  • 1
  • 1
Kamil Szot
  • 17,436
  • 6
  • 62
  • 65
-4

Define and initialize a Scanner variable named inSS that creates an input string stream using the String variable myStrLine.

Ans: Scanner inSS = new Scanner(myStrLine);