views:

379

answers:

3

I am a little confused here.

I would like to do something like this:

  1. create some kind of buffer I can write into
  2. clear the buffer
  3. 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
  4. use the contents of the buffer and print it to several PrintStream objects
  5. 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?

+3  A: 

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.

Jason S
+1  A: 

Why is it a pain to create a new buffer in the loop? That's what the garbage collector is there fore. There would need to be a new allocation under the covers in clear anyway.

If you really want to implement your SupperBuffer, 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 supper buffer if you wanted.

Chad Okere
A: 

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();
}
Dave Ray