In this short guide you are going to see how to write to multiple files at-once in Java. The technique you will see here will allow you to write the same data to multiple output streams in one go, which will keep your code shorter, readable and safer from errors that can come through copy-and-pasting.
The rationale
First of all, why would you want to write to multiple output streams at once?
The answer is simple, you may need to write the same content to multiple files. Another example is a scenario where your Rest API produces a File of some sort and you would like to keep a backup of the content you sent to the client on disk; essentially you have to write this content twice.
Writing to two files at once
The code listing below shows how we would copy content from a file named input.txt
to two other files, output-1.txt
and /backup/output-1.txt
. As you can see, we wrap the two file output streams using a class named MultiplexOutputStream
. This is the class that does most of the hardwork for us, it extends Java’s java.io.OutputStream
class and, therefore, allows you to perform all the operations you normally would on an on OutputStream
.
public class MultiplexOutputStreamExample {
public static void main(String... args) throws IOException {
File file1 = new File("output-1.txt");
File file2 = new File("/backup/output-1.txt");
try (FileOutputStream fos1 = new FileOutputStream(file1);
FileOutputStream fos2 = new FileOutputStream(file2);
MultiplexOutputStream mos = new MultiplexOutputStream(fos1, fos2)) {
Files.copy(Paths.get("input.txt"), mos);
}
}
}
The code below presents the complete code for the MultiplexOutputStream class and can be copied to your project to enable you to write to multiple output streams in one go.
import java.io.IOException;
import java.io.OutputStream;
/**
* <p>
* MultiplexOutputStream allows you to write to multiple output streams "at once".
* It allows you to use one outputstream writer to write to multiple outputstreams
* without repeating yourself.
* </p>
* <strong>Example:</strong>
*
* <pre>
* File file1 = new File("file1.java");
* File file2 = new File("file2.java");
*
* try (FileOutputStream fos1 = new FileOutputStream(file1);
* FileOutputStream fos2 = new FileOutputStream(file2);
* MultiplexOutputStream mos = new MultiplexOutputStream(fos1, fos2)) {
*
* Files.copy(Paths.get("MultiplexOutputStream.java"), mos);
*
* } catch(IOException ex) {
* ex.printStackTrace();
* }
* </pre>
*/
public class MultiplexOutputStream extends OutputStream {
private OutputStream[] outputStreams;
public MultiplexOutputStream(OutputStream... outputStreams) {
java.util.Objects.requireNonNull(outputStreams);
assert(outputStreams.length > 0);
for(Object o: outputStreams) {
java.util.Objects.requireNonNull(o);
}
this.outputStreams = outputStreams;
}
@Override
public void write(int b) throws IOException {
for(OutputStream os: outputStreams) {
os.write(b);
}
}
@Override
public void write(byte[] b) throws IOException {
for(OutputStream os: outputStreams) {
os.write(b);
}
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
for(OutputStream os: outputStreams) {
os.write(b, off, len);
}
}
@Override
public void flush() throws IOException {
for(OutputStream os: outputStreams) {
os.flush();
}
}
@Override
public void close() throws IOException {
for(OutputStream os: outputStreams) {
os.close();
}
}
}
Conclusion
Using the MultiplexOutputStream
class presented in this article, you can write fewer lines of code to write the same data to multiple files or other output streams without repeating yourself.
I hope you found this post useful.
Zikani.