如何一次将数据写入两个java.io.OutputStream对象?

时间:2011-11-02 21:13:13

标签: java io outputstream

我正在寻找神奇的Java类,这将允许我做这样的事情:

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
FileOutputStream fileStream = new FileOutputStream(new File("/tmp/somefile"));

MultiOutputStream outStream = new MultiOutputStream(byteStream, fileStream);

outStream.write("Hello world".getBytes());

基本上,我希望tee用于Java中的OutputStream。有什么想法吗?

谢谢!

5 个答案:

答案 0 :(得分:39)

答案 1 :(得分:21)

滚动你自己。根本没有任何魔法。使用Apache's TeeOutputStream您基本上可以使用下面的代码。当然使用Apache Commons I / O库可以利用其他类,但有时实际上为自己编写一些东西是很好的。 :)

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

使用以下

测试上述类
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();
}

会打印Hello World!Hello World!

(注意:被覆盖的close()可以使用一些关注':)

答案 2 :(得分:3)

刚发现这个帖子因为我不得不面对同样的问题。 如果有人想看我的解决方案(java7代码):

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

}

到目前为止工作正常,只是测试了一些基本操作,例如从System.out Stream和2个PrintStream中设置MultiOutputStream,每个都写入一个单独的日志。 我用了

System.setOut(multiOutputStream);

写入我的终端屏幕和两个没有任何问题的日志。

答案 3 :(得分:2)

滚动你自己,它基本上是微不足道的。使用ArrayList<OutputStream>或当今流行的任何内容来存储您想要的所有流,并编写write方法来循环遍历所有流,并写入每个流。

答案 4 :(得分:0)

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