mediautil.gen.directio
Class SplitInputStream

java.lang.Object
  extended by java.io.InputStream
      extended by java.io.FilterInputStream
          extended by mediautil.gen.directio.SplitInputStream
All Implemented Interfaces:
Closeable

public class SplitInputStream
extends FilterInputStream

This class enables the Sharing of an InputStream (Say from a file) by One or more IterativeReaders with a main reader. The main reader is any reader like say an ImageReader for reading images.

This is accomplished by using a common buffer. The read/skip calls on this class by the main reader calls nextRead() on the SubStreams to consume the buffered data before the buffer is filled again.

See Also:
IterativeReader

Constructor Summary
SplitInputStream(InputStream mainStream)
          Creates a new SplitInputStream Object with default parameters.
SplitInputStream(InputStream mainStream, int bufSize, int incSize)
          Creates a new SplitInputStream Object.
 
Method Summary
 int attachSubReader(IterativeReader code, InputStream subStream)
          This call must follow a createSubStream() call to attach an IterativeReader to read from the subStream created.
 int available()
          Available method of the SplitInputStream.
 InputStream createSubStream()
          Creates a Sub Stream for use by an instance of IterativeReader.
 InputStream createSubStream(int minReadSize, int readCushion)
          Creates a Sub Stream for use by an instance of IterativeReader.
 void detachSubReader(int subReaderId)
          Detaches a Sub Reader and its Stream.
 int getMaxBufSize()
          Returns the max bufSize.
 int read()
          Read method of the SplitInputStream.
 int read(byte[] b, int off, int len)
          Read method of the SplitInputStream.
 long skip(long n)
          Skip method of the SplitInputStream.
 void wrapup()
          This should be called when the Main Object (Say ImageReader) has finished reading.
 
Methods inherited from class java.io.FilterInputStream
close, mark, markSupported, read, reset
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

SplitInputStream

public SplitInputStream(InputStream mainStream,
                        int bufSize,
                        int incSize)
Creates a new SplitInputStream Object. This can be used as an Input Stream.

Parameters:
mainStream - The main input Stream, say a FileInputStream. Note that this need not be buffered since SplitInputStream itself does buffering. The Main Object (Say ImageReader) will read from the newly constructed SplitInputStream object after attaching zero or more IterativeReaders. The SplitInputStream and Sub Streams see the same data as in mainStream.
bufSize - The Initial BufferSize. This will be increased if one of the Sub Readers read way beyond the requested Size
incSize - The buffer Size is always increase/decreased in multiples of incSize

SplitInputStream

public SplitInputStream(InputStream mainStream)
Creates a new SplitInputStream Object with default parameters. The bufSize used is 5120 bytes, incSize used is 1024.

Parameters:
mainStream - The main input Stream, say a FileInputStream. Note that this need not be buffered since SplitInputStream itself does buffering. The Main Object (Say ImageReader) will read from the newly constructed SplitInputStream object after attaching zero or more IterativeReaders. The SplitInputStream and Sub Streams see the same data as in mainStream.
Method Detail

createSubStream

public InputStream createSubStream(int minReadSize,
                                   int readCushion)
Creates a Sub Stream for use by an instance of IterativeReader. The SubStream sees the same data as in the mainStream. The Buffer Size of the SplitInputStream if less than (minReadSize+readCushion+512) is resized to that value.

Parameters:
minReadSize - The minimum Number of Bytes that should be passed to the nextRead method of the IterativeReader. This value is limited to atleast 512.
readCushion - The maximum number of bytes by which a nextRead() call to the subReader may overshoot the requested number of bytes. If a nextRead() call exceeds the limit beyond readCushion a buffer expansion may result which affects performance. This value is limited to atleast 512.
Returns:
An InputStream which also implements ByteCounter which can be used by the IterativeReader to keep track of the bytes read/skipped. This Input Stream must be used directly (without creating a BufferedInputStream) by an Object implementing IterativeReader. The attachSubReader() method must be called with the IterativeReader Object and this return value after this call.

Please note that the returned Input Stream does not strictly confirm to jdk's InputStream spec in the following:

  • The Skip call always skips the required number of bytes unless the end of file has already been detected. This is because for skip just the internal q pointers are incremented without actually checking for the end of file. This is to avoid possible unnecessary buffering of data.
  • available always returns atleast 1 unless the end of file has been detected
See Also:
IterativeReader, attachSubReader(IterativeReader, InputStream), ByteCounter

createSubStream

public InputStream createSubStream()
Creates a Sub Stream for use by an instance of IterativeReader. A minimum read Size of 750 and a read Cushion of 750 is used.

Returns:
An InputStream which also implements ByteCounter which can be used by the IterativeReader to keep track of the bytes read/skipped. This Input Stream must be used directly (without creating a BufferedInputStream) by an Object implementing IterativeReader. The attachSubReader() method must be called with the IterativeReader Object and this return value after this call.

Please note that the returned Input Stream does not strictly confirm to jdk's InputStream spec in the following:

  • The Skip call always skips the required number of bytes unless the end of file has already been detected. This is because for skip just the internal q pointers are incremented without actually checking for the end of file. This is to avoid possible unnecessary buffering of data.
  • available always returns atleast 1 unless the end of file has been detected
See Also:
IterativeReader, attachSubReader(IterativeReader,InputStream), ByteCounter

attachSubReader

public int attachSubReader(IterativeReader code,
                           InputStream subStream)
This call must follow a createSubStream() call to attach an IterativeReader to read from the subStream created. This subReader is detached by a detachSubReader(..) call or when the nextRead() method returns IterativeReader.STOP or when the subStream is closed.

Parameters:
code - The IterativeReader to share the main Input. The nextRead() method is called on code by the read/skip calls on SplitInputStream as and when required.
subStream - The SubStream which was created using createSubStream() call and not yet attached. The nextRead() calls to the IterativeReader specified by the parameter code must read from this subStream.
Returns:
An integer representing a SubReader Id. This id should be passed if a stream is required to be detached.
See Also:
IterativeReader.nextRead(int), createSubStream(int,int), detachSubReader(int)

detachSubReader

public void detachSubReader(int subReaderId)
Detaches a Sub Reader and its Stream. Note that it is not necessary to call this method explicitly as the Sub Reader is automatically detached when the nextRead() returns IterativeReader.STOP or when the subStream is closed.

Parameters:
subReaderId - Id to detach
See Also:
attachSubReader(IterativeReader,InputStream)

read

public int read(byte[] b,
                int off,
                int len)
         throws IOException
Read method of the SplitInputStream. See the documentation of InputStream.read(..) for more information. This reads from the underlying InputStream and buffers the data for use by the subReaders.

Overrides:
read in class FilterInputStream
Throws:
IOException - If the underlying stream throws an IOException or if the nextRead() call of a subReader throws an IOException

read

public int read()
         throws IOException
Read method of the SplitInputStream. See the documentation of InputStream.read(..) for more information. This reads from the underlying InputStream and buffers the data for use by the subReaders.

Overrides:
read in class FilterInputStream
Throws:
IOException - If the underlying stream throws an IOException or if the nextRead() call of a subReader throws an IOException

skip

public long skip(long n)
          throws IOException
Skip method of the SplitInputStream. See the documentation of InputStream.skip(..) for more information. This skips from the underlying InputStream and buffers the data for use by the subReaders.

Overrides:
skip in class FilterInputStream
Throws:
IOException - If the underlying stream throws an IOException or if the nextRead() call of a subReader throws an IOException

available

public int available()
Available method of the SplitInputStream. See the documentation of InputStream.available(..) for more information. This method does not strictly conform to InputStream spec since it always returns atleast 1 unless the end of file is reached.

Overrides:
available in class FilterInputStream

getMaxBufSize

public int getMaxBufSize()
Returns the max bufSize. For debugging and informational purposes.

Returns:
Max Buf Size

wrapup

public void wrapup()
            throws IOException
This should be called when the Main Object (Say ImageReader) has finished reading. This is to ensure that all the SubReaders finish reading any data left in the buffer/mainStream and detach.

Throws:
IOException