PrintWriter for multiple files

I need to write the same text for multiple files (or streams). Sometimes I need to use Writer, sometimes PrintWriter, sometimes OutputStream ...

One way to do this is to extend PrintWriter to have an array of PrintWriters and override each method as follows:

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

(and the same for Writer, OutputStream ...)

Is there a better alternative? Is it already implemented in the library?

+4
source share
5 answers

There are already libraries for this. If you can use OSS, then take the Apache Commons IO and see TeeOutputStream . Here is a sample code illustrating its use:

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

You can use TeeOutputStream wherever a regular OutputStream will be accepted, or wrap it in Writer , depending on what you need.

+2
source

You do not need to override all methods in PrintWriter , since all printXyz methods printXyz delegated to the underlying write methods of the Writer API.

Although: PrintWriter has a PrintWriter(Writer out) constructor. Therefore, you only need to implement the new Writer with _one_method:

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

use it as follows:

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

This will take care of Writers .

You can do the same trick using OutputStream . You can also simply implement MultiOutputStream , skip MultiWriter and use the delegation chain PrintWriter->OutputStreamWriter->MultiOutputStream . This will be just one method in one class to implement, and you will only get PrintWriter , Writer and OutputStream .

+2
source

If you can use the logbook ...

Use the logging library and define a few add-ons in your configuration.

You can use Apache Log4J or LogBack (I would recommend LogBack, but each one).

If you are forced to use PrintWriter ...

Unfortunately, your solution is the best.

There is an alternative, but it is not very. If you are forced to pass PrintWriter without providing an extension to add to the trusted JREs at boot time, replace PrintWriter class that acts essentially what you are offering, I don’t think you have a choice.

+1
source

Well, actually you could do it easily:

instead of overriding all the methods of the PrintWriter class, you can override only one method of the Writer class:

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

because all other methods ( print(...) and other write(...) -s) use this:

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

UPD: also flush() and close() .

For OutputStream the same situation is with public void write(int b) method

+1
source

I prefer the composition to expand. Here is another option:

  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);
             }
         }
 }
0
source

Source: https://habr.com/ru/post/1485041/


All Articles