Java中的printf()功能与CharBuffer或类似功能相结合

时间:2009-01-02 15:11:25

标签: java stream printf

我在这里有点困惑。

我想做这样的事情:

  1. 创建一些我可以写入的缓冲区
  2. 清除缓冲区
  3. 使用类似printf()的函数多次将一堆东西附加到缓冲区中,基于一些复杂的计算,我只想做一次
  4. 使用缓冲区的内容并将其打印到多个PrintStream个对象
  5. 根据需要重复步骤2-4
  6. 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());
    }
    

    看起来在PrintWriter周围包裹StringWriter会为上面的sb对象执行我想要的操作,除了没有clear()方法。我想我每次都可以通过循环创建一个新的PrintWriter和StringWriter对象,但这看起来很痛苦。 (在我的真实代码中,我在几个地方这样做,而不是只在一个循环中执行一次......)

    我也经常使用java.nio.CharBuffer和其他NIO缓冲区,这似乎是一种很有前景的方法,但我不知道如何用一个会给我{{1}的对象包装它们功能。

    任何建议?

3 个答案:

答案 0 :(得分:3)

啊:我想我已经知道了。 Formatter类有format()方法,类似于printf(),它可以构造为包围任何实现Appendable的对象。 CharBuffer实施Appendable,我可以clear()或在必要时宣读CharBuffer的内容。

答案 1 :(得分:1)

为什么在循环中创建新缓冲区很麻烦?这就是垃圾收集器的用途。无论如何,需要在clear()的封面下进行新的分配。

如果你真的想要实现你的SuperBuffer,那就不会那么难了。只需使用clear()函数创建OutputStream的子类,然后围绕它包装PrintStream。如果需要,可以在超级缓冲区中使用CharBuffer。

答案 2 :(得分:0)

考虑创建一个OutputStream(或Writer)的子类TeeOutputStream,它保存您的数组流和委托给它们。然后使用PrintStream(或PrintWriter)包装您的流,并在其上调用printf()。不需要临时缓冲区或任何东西:

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