How to write data to two java.io.OutputStream objects at once?

前端 未结 5 900
野性不改
野性不改 2020-11-27 20:37

I\'m looking for magical Java class that will allow me to do something like this:

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
FileOutputS         


        
相关标签:
5条回答
  • 2020-11-27 21:10

    Just found this thread beacause I had to face the same problem. If someone wants to see my solution (java7 code):

    package Core;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    
    public class MultiOutputStream extends OutputStream {
    
    private List<OutputStream> out;
    
    public MultiOutputStream(List<OutputStream> outStreams) {
    
        this.out = new LinkedList<OutputStream>();
    
        for (Iterator<OutputStream> i = outStreams.iterator(); i.hasNext();) {
            OutputStream outputStream = (OutputStream) i.next();
    
            if(outputStream == null){
                throw new NullPointerException();
            }
            this.out.add(outputStream);
        }
    }
    
    @Override
    public void write(int arg0) throws IOException {
    
        for (Iterator<OutputStream> i = out.iterator(); i.hasNext();) {
            OutputStream var = (OutputStream) i.next();
    
            var.write(arg0);
        }
    }
    
    @Override
    public void write(byte[] b) throws IOException{
    
        for (Iterator<OutputStream> i = out.iterator(); i.hasNext();) {
            OutputStream var = (OutputStream) i.next();
    
            var.write(b);
        }
    }
    
    @Override
    public void write(byte[] b, int off, int len) throws IOException{
    
        for (Iterator<OutputStream> i = out.iterator(); i.hasNext();) {
            OutputStream var = (OutputStream) i.next();
    
            var.write(b, off, len);
        }
    }
    
    @Override
    public void close() throws IOException{
    
        for (Iterator<OutputStream> i = out.iterator(); i.hasNext();) {
            OutputStream var = (OutputStream) i.next();
    
            var.close();
        }
    }
    
    @Override
    public void flush() throws IOException{
    
        for (Iterator<OutputStream> i = out.iterator(); i.hasNext();) {
            OutputStream var = (OutputStream) i.next();
    
            var.flush();
        }
    }
    
    }
    

    Works fine so far, just tested some basic operation, e.g. setting up a MultiOutputStream from the System.out Stream and 2 PrintStreams each writing into a seperate log. I used

    System.setOut(multiOutputStream);
    

    to write to my terminal screen and two logs which worked without any problems.

    0 讨论(0)
  • 2020-11-27 21:12

    Roll your own, it's basically trivial. Use an ArrayList<OutputStream> or whatever's popular nowadays to store all the streams you want and write the write method to loop over all of them, writing to each.

    0 讨论(0)
  • 2020-11-27 21:17

    Just roll your own. There isn't any magic at all. Using Apache's TeeOutputStream you would basically use the code below. Of course using the Apache Commons I/O library you can leverage other classes, but sometimes it is nice to actually write something for yourself. :)

    public final class TeeOutputStream extends OutputStream {
    
      private final OutputStream out;
      private final OutputStream tee;
    
      public TeeOutputStream(OutputStream out, OutputStream tee) {
        if (out == null)
          throw new NullPointerException();
        else if (tee == null)
          throw new NullPointerException();
    
        this.out = out;
        this.tee = tee;
      }
    
      @Override
      public void write(int b) throws IOException {
        out.write(b);
        tee.write(b);
      }
    
      @Override
      public void write(byte[] b) throws IOException {
        out.write(b);
        tee.write(b);
      }
    
      @Override
      public void write(byte[] b, int off, int len) throws IOException {
        out.write(b, off, len);
        tee.write(b, off, len);
      }
    
      @Override
      public void flush() throws IOException {
        out.flush();
        tee.flush();
      }
    
      @Override
      public void close() throws IOException {
        try {
          out.close();
        } finally {
          tee.close();
        }
      }
    }
    

    Testing with the above class with the following

    public static void main(String[] args) throws IOException {
      TeeOutputStream out = new TeeOutputStream(System.out, System.out);
      out.write("Hello world!".getBytes());
      out.flush();
      out.close();
    }
    

    would print Hello World!Hello World!.

    (Note: the overridden close() could use some care tho' :)

    0 讨论(0)
  • 2020-11-27 21:27

    Try the Apache Commons TeeOutputStream.

    0 讨论(0)
  • 2020-11-27 21:30
    final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    final FileOutputStream fileStream = new FileOutputStream(new File("/tmp/somefile"));
    OutputStream outStream = new OutputStream() {
    
        public void write(int b) throws IOException {
            byteStream.write(b);
            fileStream.write(b);
        }
    };
    outStream.write("Hello world".getBytes());
    
    0 讨论(0)
提交回复
热议问题