TimeoutOutputStream.java
package gov.usgs.earthquake.util;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* An output stream that self-closes if the specified timeout elapses between
* writes.
*/
public class TimeoutOutputStream extends FilterOutputStream implements Runnable {
/** write timeout in milliseconds. */
private final long timeout;
/** thread that enforces timeout. */
private final Thread timeoutThread;
/** flag for timeoutThread to terminate. */
private boolean closed = false;
/**
* Create a TimeoutOutputStream.
*
* @param out
* the wrapped output stream.
* @param timeout
* the timeout in milliseconds between writes. If this timeout
* completes, the underlying stream will be closed.
*/
public TimeoutOutputStream(final OutputStream out, final long timeout) {
super(out);
this.timeout = timeout;
this.timeoutThread = new Thread(this);
this.timeoutThread.start();
}
@Override
public void write(int b) throws IOException {
// pass directly to underlying stream
this.out.write(b);
timeoutThread.interrupt();
}
@Override
public void write(byte[] buf) throws IOException {
// pass directly to underlying stream
this.out.write(buf);
timeoutThread.interrupt();
}
@Override
public void write(byte[] buf, int offset, int length) throws IOException {
// pass directly to underlying stream
this.out.write(buf, offset, length);
timeoutThread.interrupt();
}
@Override
public void close() throws IOException {
closed = true;
try {
super.close();
} finally {
// interrupt in case close called from outside timeoutThread
timeoutThread.interrupt();
}
}
@Override
public void run() {
while (!closed) {
try {
// wait for timeout milliseconds
Thread.sleep(timeout);
// timeout elapsed, close stream
try {
close();
} catch (IOException e) {
}
} catch (InterruptedException ie) {
// a write occured
}
}
}
}