printf() functionality in Java combined with a CharBuffer or something like it
Question
I am a little confused here.
I would like to do something like this:
- create some kind of buffer I can write into
- clear the buffer
- use a printf()-like function several times to append a bunch of stuff into the buffer based on some complicated calculations I only want to do once
- use the contents of the buffer and print it to several
PrintStream
objects - repeat steps 2-4 as necessary
e.g.:
SuperBuffer sb = new SuperBuffer();
/* SuperBuffer is not a real class, so I don't know what to use here */
PrintStream[] streams = new PrintStream[N];
/* ... initialize this array to several streams ... */
while (!done)
{
sb.clear();
sb.printf("something %d something %d something %d",
value1, value2, value3);
if (some_complicated_condition())
sb.printf("something else %d something else %d", value4, value5);
/* ... more printfs to sb ... */
for (PrintStream ps : streams)
ps.println(sb.getBuffer());
}
It looks like wrapping a PrintWriter around StringWriter will do what I want for the sb
object above, except there's no clear()
method. I suppose I could create a new PrintWriter and StringWriter object each time through the loop, but that seems like a pain. (in my real code I do this in several places, not just once in one loop...)
I've also used java.nio.CharBuffer
and other NIO buffers a lot, and that seems like a promising approach, but I'm not sure how I can wrap them with an object that will give me printf()
functionality.
any advice?
Solution
ah: I think I've got it. The Formatter
class has a format()
method that's like printf()
, and it can be constructed to wrap around any kind of object that implements Appendable
. CharBuffer
implements Appendable
, and I can clear()
or read out the contents of the CharBuffer
as necessary.
OTHER TIPS
Why is it a pain to create a new buffer in the loop? That's what the garbage collector is there for. There would need to be a new allocation under the covers in clear() anyway.
If you really want to implement your SuperBuffer, it would not be that hard at all. Just create a subclass of OutputStream with a clear() function, and then wrap a PrintStream around that. You could use a CharBuffer in your super buffer if you wanted.
Consider creating a subclass, TeeOutputStream, of OutputStream (or Writer) that holds your array of streams and delegates to them. Then wrap your stream with a PrintStream (or PrintWriter) and just call printf() on it. No need for a temp buffer or anything:
PrintStream[] streams = new PrintStream[N]; // any output streams really
PrintStream ps = new PrintStream(new TeeOutputStream(streams));
while (!done)
{
ps.printf("something %d something %d something %d",
value1, value2, value3);
if (some_complicated_condition())
ps.printf("something else %d something else %d", value4, value5);
ps.println();
}