Class PipeReaderThread

  • All Implemented Interfaces:
    java.lang.Runnable

    public abstract class PipeReaderThread
    extends java.lang.Thread
    Thread which reads data from a pipe. Having got an instance of this class, you can call its getOutputStream method to acquire a stream to write into, and then implement its doReading(java.io.InputStream) method to process the data; this method runs in the new thread.

    Here is an example of using the class to count the bytes written down a stream:

         PipeReaderThread reader = new PipeReaderThread() {
            protected void doReading( InputStream dataIn ) throws IOException {
                int i;
                while ( dataIn.read() >= 0 ) i++;
                System.out.println( i );
            }
         };
         reader.start();
         OutputStream dataOut = reader.getOutputStream();
         // write bytes down dataOut ...
         dataOut.close();
         reader.finishReading();
     
    Other uses will look pretty similar, but just override doReading in different ways. Note that any exceptions thrown by doReading are caught and eventually thrown in the reader thread by finishReading. The same exception may also be thrown by the write method of the writer thread.

    This class serves two purposes. Firstly it copes with IOExceptions encountered during the read, and makes sure they get thrown at the writing end of the pipe (doReading is declared to throw IOException). Secondly it shields the user from the implementation of the piped connection. Performance of the PipedInputStream/PipedOutputStream is dismal - this class may be able to do better.

    The current implementation uses a couple of drop-in Piped*Stream replacements, but performance still isn't great - it may be possible to do better in future. You can provide your own paired pipes by overriding both getInputStream() and getOutputStream().

    Author:
    Mark Taylor (Starlink)
    • Nested Class Summary

      • Nested classes/interfaces inherited from class java.lang.Thread

        java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler
    • Field Summary

      • Fields inherited from class java.lang.Thread

        MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
    • Constructor Summary

      Constructors 
      Constructor Description
      PipeReaderThread()
      Constructs a new reader thread.
    • Method Summary

      All Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      protected abstract void doReading​(java.io.InputStream dataIn)
      This method should be implemented to consume all the bytes in the given input stream.
      void finishReading()
      Waits until the doReading method has finished reading the bytes written down the output stream, and returns.
      protected java.io.InputStream getInputStream()
      Returns the stream at the input end of the pipe.
      java.io.OutputStream getOutputStream()
      Returns the stream at the output end of the pipe.
      void run()
      Implements the thread's run method to invoke doReading, catching and saving IOExceptions.
      • Methods inherited from class java.lang.Thread

        activeCount, checkAccess, clone, countStackFrames, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, onSpinWait, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, suspend, toString, yield
      • Methods inherited from class java.lang.Object

        equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • PipeReaderThread

        public PipeReaderThread()
                         throws java.io.IOException
        Constructs a new reader thread.
        Throws:
        java.io.IOException
    • Method Detail

      • getInputStream

        protected java.io.InputStream getInputStream()
        Returns the stream at the input end of the pipe.
        Returns:
        input stream
      • getOutputStream

        public java.io.OutputStream getOutputStream()
        Returns the stream at the output end of the pipe.
        Returns:
        output stream
      • run

        public void run()
        Implements the thread's run method to invoke doReading, catching and saving IOExceptions.
        Specified by:
        run in interface java.lang.Runnable
        Overrides:
        run in class java.lang.Thread
      • doReading

        protected abstract void doReading​(java.io.InputStream dataIn)
                                   throws java.io.IOException
        This method should be implemented to consume all the bytes in the given input stream. It is probably a good idea for implementations to buffer the supplied input stream for efficiency. Note that any implementation of this method which does not read dataIn to the end of the stream (either closing it early or just stopping reading) may cause an IOException to be thrown in the thread which is writing to the PipedOutputStream.
        Parameters:
        dataIn - stream which will supply bytes
        Throws:
        java.io.IOException - if any I/O error occurs; this exception will be saved and thrown later by the finishReading method
      • finishReading

        public void finishReading()
                           throws java.io.IOException
        Waits until the doReading method has finished reading the bytes written down the output stream, and returns. Any IOException which has occurred during the read will be thrown by this method.
        Throws:
        java.io.IOException