gausssoft.io
Class ChunkingOutputStream

java.lang.Object
  |
  +--java.io.OutputStream
        |
        +--java.io.FilterOutputStream
              |
              +--gausssoft.io.StatusOutputStream
                    |
                    +--gausssoft.io.ChunkingOutputStream
Direct Known Subclasses:
BandwidthOutputStream

public class ChunkingOutputStream
extends StatusOutputStream

This class wraps around another InputStream and writes data in chunks.

The main use for this class is to provide an "interrupt" during I/O operations. The interrupt() method is then overridden by subclasses to perform any task. This is mainly useful for multi-thread access to a single stream. See BandwidthControlledInputStream for an example of this.

Another example would be to use the chunking so that the StatusOutputStream.getCount() method becomes more responsive, especially if you are using it in a multi-threaded environment. The count is adjusted after each successful method call return. If a large amount of data is passed to the underlying stream in one method call, the counter will not be updated until the data has been passed through. However, chunking the data will mean the counter gets updated whilst data is passing through it.

There are four settings you can use for the implementation of the stream.

In the first case (using the figure provided by getCount), this means that interrupt is called after a certain amount of bytes are written to the stream, regardless of what methods are called to cross this barrier. So, let us take the example, of a stream that is set to call interrupt after 750 bytes are written to it, uses this method of calculating using getCount.

Let's say that there are two method calls, write(bytes, 0, 1000) and write(bytes, 0, 600) meaning you write 1000 and then 600 bytes out. In the first method call there will only be 750 bytes written out, and then the interrupt method will be called. It will then write out the last 250 bytes and return. The second call will write out 500 bytes, call interrupt, then write out the remaining 100 bytes and return. This is because after the first call is performed, there are 250 bytes that have been written out since the last interrupt.

In the same example using the second method (using an internal method count), the first method call will call interrupt at the same time. In the second method call, it will not be called at all. This is simply because it calls interrupt after 750 bytes per method call. Because the second method call does not pass more than 600 bytes, it does not call interrupt.

The interrupt method is intended to be overridden by other classes, however, the interrupt method is used by this object to respond to any calls to change the interrupt level. Therefore, it is recommended that any subclass that overrides this method calls the interrupt method at the end of the method call.

The chunk size used may be modified at any point, but a count is kept of how many bytes have passed since the last interrupt was called (if the stream is cumulative). For example, if you had a chunk size of 5000, and had written out 3500 bytes, and you then set the chunk size to 1000, only one byte would pass through before the interrupt method is called. This is to the stream will react to changes in interrupt levels correctly.

Although you may use end of method interrupts, and use the cumulative method for calculations, this is a slightly unusual combination, since you adopt a style of chunking which is cumulative, and also method-call dependent. In the above example, if you use end of method calls as well as cumulative calculations, end of method calls to interrupt do not reset the counter which tracks the number of bytes that have passed since the last interrupt call.

Since:
GSDK 1.1
Author:
Allan Crooks
See Also:
interrupt(), ChunkingOutputStream

Fields inherited from class java.io.FilterOutputStream
out
 
Constructor Summary
ChunkingOutputStream(OutputStream out, int chunksize, boolean cumulative, boolean end, boolean start)
          Creates a ChunkingOutputStream.
 
Method Summary
 int getChunkSize()
          Returns the current chunk size used.
protected  void interrupt()
          This method is called after a certain amount of bytes have been written out to the underlying stream.
 void setChunkSize(int size)
          Sets a new value for the chunk size.
protected  void updateChunkSize()
          This method provides a way of forcing this object to update the value used by the chunk size.
 void write(byte[] b)
           
 void write(byte[] b, int off, int len)
           
 void write(int i)
           
 
Methods inherited from class gausssoft.io.StatusOutputStream
close, flush, getCount, isClosed
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ChunkingOutputStream

public ChunkingOutputStream(OutputStream out,
                            int chunksize,
                            boolean cumulative,
                            boolean end,
                            boolean start)
Creates a ChunkingOutputStream.
Parameters:
out - The OutputStream to wrap around.
chunksize - The chunk size to use.
cumulative - true if this object should use the getCount method for calculations, false to use an internal counter.
end - true if this object should perform end-of-call interrupts.
start - true if this object should perform start-of-call interrupts.
Throws:
NullPointerException - If out is null.
IllegalArgumentException - If chunksize is less than 1.
Method Detail

interrupt

protected void interrupt()
This method is called after a certain amount of bytes have been written out to the underlying stream. This method is intended to be overridden by subclasses, but overriding methods must call this method at the end of the overridden method.

At this implementation, this method deals with any request to change the size of the chunks created (it calls the updateChunkSize() method).

See Also:
updateChunkSize()

updateChunkSize

protected final void updateChunkSize()
This method provides a way of forcing this object to update the value used by the chunk size. This is the method called by this implementation of the interrupt() method.
See Also:
interrupt()

getChunkSize

public final int getChunkSize()
Returns the current chunk size used.

If the setChunkSize(int) method is called prior to calling this, it will return the old chunk size value if the interrupt method has not been called since the chunk size was modified.

Returns:
The current chunk size used.

setChunkSize

public final void setChunkSize(int size)
Sets a new value for the chunk size.

The new value will not be used until the interrupt method has been called.

Parameters:
size - The new chunk size to use.
Throws:
IllegalArgumentException - If size is less than 1.

write

public void write(int i)
           throws IOException
Overrides:
write in class StatusOutputStream

write

public void write(byte[] b)
           throws IOException
Overrides:
write in class StatusOutputStream

write

public void write(byte[] b,
                  int off,
                  int len)
           throws IOException
Overrides:
write in class StatusOutputStream