繁体   English   中英

PrintWriter到多个文件

[英]PrintWriter to multiple files

我需要将相同的文本写入多个文件(或流)。 有时我需要使用Writer,有时需要PrintWriter,有时需要OutputStream ...

一种解决方法是将PrintWriter扩展为具有PrintWriters数组,并按如下方法重写每个方法:

class MutiplePrintWriter extends PrintWriter {
    private PrintWriter[] outs;
    public MutiplePrintWriter(PrintWriter[] outs) { this.out = out; }

    public void print(boolean b) { for (PrintWriter out : outs) print(b); }
    public void print(char c) { for (PrintWriter out : outs) print(c); }
    public void print(char[] s) { for (PrintWriter out : outs) print(s); }
    ...
}   

(与Writer,OutputStream相同)

有更好的选择吗? 这已经在库中实现了吗?

您不需要重写PrintWriter所有方法,因为所有printXyz方法都委托给Writer API的基本write方法。

虽然: PrintWriter具有构造函数PrintWriter(Writer out) 因此,您只需要使用_one_method来实现一个新的Writer ,如下所示:

public class MultiWriter implements Writer {
    private List<Writer> delegates;

    public MultiWriter(List<Writer> delegates){
        this.delegates = delegates;
    }

    public void write(char cbuf[], int off, int len) throws IOException {
        for(Writer w: delegates){
            w.writer(cbuf, off, len);
        }
    }
}

像这样使用:

PrintWriter myPrinter = new PrintWriter(new MultiWriter(listOfDelegates));
myPrintWriter.println("Hello World!");

这将照顾Writers

您可以使用OutputStream进行相同的操作。 您也可以只实现MultiOutputStream ,省略MultiWriter并使用委托链PrintWriter->OutputStreamWriter->MultiOutputStream 这只是一个类中的一种实现方法,您可以免费获得PrintWriterWriterOutputStream

已经有用于此的库。 如果可以使用OSS,请获取Apache Commons IO ,然后看看TeeOutputStream类。 这是一些示例代码,说明其用法:

public class TeeOutputStreamTest {

   @Test
   public void testPrintToMultipleStreams() throws Exception {
      final String fileName1 = "/tmp/fileOne.txt";
      final String fileName2 = "/tmp/fileTwo.txt";
      final String fileName3 = "/tmp/fileThree.txt";

      final TeeOutputStream tos = new TeeOutputStream(new FileOutputStream(
              fileName1), new TeeOutputStream(new FileOutputStream(fileName2),
              new FileOutputStream(fileName3)));
      final PrintWriter writer = new PrintWriter(tos);

      writer.println("Hello World");
      writer.close();
   }
}

您可以在接受常规OutputStream任何地方使用TeeOutputStream ,也可以根据需要将其包装在Writer

如果可以使用日志记录库...

使用日志记录库并在其配置中定义多个追加程序。

您可以使用Apache Log4JLogBack达到这种效果(我建议使用LogBack,但要分别使用它们)。

如果您被迫使用PrintWriter ...

不幸的是,您的解决方案是最好的。

有一个替代方法,但这并不漂亮。 如果您被迫传递PrintWriter,而没有提供在加载时添加到JRE的受信任库中的扩展,以实际上执行您所建议的类替换 PrintWriter ,那么我认为您没有太多选择。

好吧,实际上您可以轻松地做到这一点:

而不是重写PrintWriter类的所有方法,您可以重写Writer类的一个方法

public void write(char cbuf[], int off, int len);

因为所有其他方法( print(...)和其他write(...) s)都使用此方法:

public void write(char cbuf[], int off, int len) {
   for (Writer out : outs) out.write(cbuf, off, len);
}

UPD:也是flush()close()方法。

对于OutputStream ,与方法public void write(int b)相同的情况

我更喜欢构图而不是扩展。 这是另一个选择:

public class MultiWriter
{
    List<PrintWriter> listPrintWriter = new LinkedList<PrintWriter>;
    List<Writer> listWriter = new LinkedList<Writer>;

    public void addPrintWriter(final PrintWriter newPrintWriter)
    {
        listPrintWriter.add(newPrintWriter);
    }

    public void addWriter(final Writer newWriter)
    {
        listWriter.add(newWriter);
    }

    public void write((char cbuf[], int off, int len)
    {
        if (listPrintWriter != null)
        {
            for (PrintWriter printWriter : listPrintWriter)
            {
                printWriter.write(cbuf, off, len);
            }
        }

        if (listWriter != null)
        {
            for (Writer writer : listWriter)
            {
                writer.write(cbuf, off, len);
            }
        }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM