Writing to multiple files in one go with Java


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.

See also