001package com.randomnoun.common.io; 002 003import java.io.IOException; 004import java.io.OutputStream; 005 006/** 007 * An outputstream which mimics the 'tee' unix utility. 008 * It writes to two outputStreams at the same time 009 */ 010public class TeeOutputStream extends OutputStream { 011 012 /** The OutputStream */ 013 protected OutputStream out; 014 015 /** The second OutputStream to write to. */ 016 protected OutputStream branch; 017 018 /** 019 * Constructs a TeeOutputStream. 020 * 021 * @param out the main OutputStream 022 * @param branch the second OutputStream 023 */ 024 public TeeOutputStream(final OutputStream out, final OutputStream branch) { 025 this.out = out; 026 this.branch = branch; 027 } 028 029 /** 030 * Writes the bytes to both streams. 031 * 032 * @param b the bytes to write 033 * @throws IOException if an I/O error occurs. 034 */ 035 @Override 036 public synchronized void write(final byte[] b) throws IOException { 037 out.write(b); 038 branch.write(b); 039 } 040 041 /** 042 * Writes the specified bytes to both streams. 043 * 044 * @param b the bytes to write 045 * @param off The start offset 046 * @param len The number of bytes to write 047 * @throws IOException if an I/O error occurs. 048 */ 049 @Override 050 public synchronized void write(final byte[] b, final int off, final int len) throws IOException { 051 out.write(b, off, len); 052 branch.write(b, off, len); 053 } 054 055 /** 056 * Writes a byte to both streams. 057 * 058 * @param b the byte to write 059 * @throws IOException if an I/O error occurs. 060 */ 061 @Override 062 public synchronized void write(final int b) throws IOException { 063 out.write(b); 064 branch.write(b); 065 } 066 067 /** 068 * Flushes both streams. 069 * 070 * @throws IOException if an I/O error occurs. 071 */ 072 @Override 073 public void flush() throws IOException { 074 out.flush(); 075 branch.flush(); 076 } 077 078 /** 079 * Closes both output streams. 080 * 081 * <p> 082 * If closing the main output stream throws an exception, attempt to close the branch output stream. 083 * </p> 084 * 085 * <p> 086 * If closing the main and branch output streams both throw exceptions, which exceptions is thrown by this method is 087 * currently unspecified and subject to change. 088 * </p> 089 * 090 * @throws IOException if an I/O error occurs. 091 */ 092 @Override 093 public void close() throws IOException { 094 try { 095 out.close(); 096 } finally { 097 branch.close(); 098 } 099 } 100 101}