Your code will probably suffer from the biggest flaw in PipedInputStream / PipedOutputStream. From the Javadoc of PipedInputStream:
A pipe is said to be broken if a thread that was providing data bytes to the connected piped output stream is no longer alive.
That means that you are going to need to keep that thread alive until you close the input stream.
I have one simple way of solving this, using a helper class:
The thread will now block until either interrupted or until the returned InputStream is closed, thereby keeping it alive long enough to not cause a broken pipe. The only way a broken pipe can now occur is either the wait being interrupted, or the reading (main?) thread ending before all output is processed.