I\'m looking for magical Java class that will allow me to do something like this:
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
FileOutputS
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.
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.
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' :)
Try the Apache Commons TeeOutputStream.
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());