wt.util
Class BlockDataOutputStream

java.lang.Object
  extended byjava.io.OutputStream
      extended byjava.io.FilterOutputStream
          extended bywt.util.BlockDataOutputStream

public class BlockDataOutputStream
extends FilterOutputStream

An output stream filter used to nest an output stream within another output stream. This stream annotates each write to the stream with a block size so that a corresponding block data input stream can detect EOF without reading past the end of the data written on this stream. It is designed to allow efficient pass through of large blocks over buffered streams by combining block header and block data in a single write when possible. The close method must be called to mark the end of the stream.

To enable efficient write through to underlying buffered output streams, a new writeThrough method is provided where the caller can leave room in their byte array for the block header (max 4 bytes). When calling this method, the beginning offset should be greater than 3.

WARNING: The write method will also perform this optimization, but it will restore the previous bytes into the buffer before returning. However, since the data in the buffer is temporarily changed, the write is not thread safe. This behavior could be a problem if writing from a circular buffer being filled by another thread. Luckily, java.io.PipedOutputStream is still safe because the circular buffer is on the reading side, as will usually be the case.

This class is used to replace streaming in block data mode within object output streams which, beginning in JDK 1.2, impose a 1024 byte canonical block size on primitive data in Serializable objects. The small buffer size can cause extra overhead when writing through to a buffered stream with a larger buffer size. This class can be used by Externalizable objects to achieve efficient write through of larger blocks.

Block header is variable length. The number of bytes is indicated by the high order bits of the first byte. If block up to 127 bytes (0x7F), a single byte is used with zero in the high order bit. If 128 to 16383 (0x3FFF), two bytes are used with one and zero in the high order bits of the first byte. If 16384 to 131071 (0x1FFFF), three bytes are used with one, one, and zero in the high order bits of the first byte. Larger writes will use a 4 byte header with all 3 high order bits set, resulting in a maximum block size of 536870911 (0x1FFFFFFF). The end of the stream is marked by a 4 byte header specifying zero length (0xE0000000), allowing 4 byte read ahead to be safe from consuming any underlying stream.


Nested Class Summary
(package private)  class BlockDataOutputStream.Buffered
           
 
Field Summary
private  boolean closed
           
private static boolean DEBUG
           
private  byte[] header
           
private  byte[] save
           
 
Fields inherited from class java.io.FilterOutputStream
out
 
Constructor Summary
BlockDataOutputStream(OutputStream output_stream)
           
 
Method Summary
 void close()
           
 OutputStream newBufferedOutputStream(int size)
          Create a buffered output stream that will efficiently write through this block data stream so that header and block data pass through a single write call to the underlying output stream.
private  int prepareHeader(int len)
           
 void write(byte[] buf, int off, int len)
           
 void write(int b)
           
 void writeThrough(byte[] buf, int off, int len)
           
 
Methods inherited from class java.io.FilterOutputStream
flush, write
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

header

private byte[] header

save

private byte[] save

closed

private boolean closed

DEBUG

private static final boolean DEBUG
See Also:
Constant Field Values
Constructor Detail

BlockDataOutputStream

public BlockDataOutputStream(OutputStream output_stream)
Method Detail

write

public void write(int b)
           throws IOException
Throws:
IOException

write

public void write(byte[] buf,
                  int off,
                  int len)
           throws IOException
Throws:
IOException

writeThrough

public void writeThrough(byte[] buf,
                         int off,
                         int len)
                  throws IOException
Throws:
IOException

prepareHeader

private int prepareHeader(int len)

close

public void close()
           throws IOException
Throws:
IOException

newBufferedOutputStream

public OutputStream newBufferedOutputStream(int size)
Create a buffered output stream that will efficiently write through this block data stream so that header and block data pass through a single write call to the underlying output stream.

Since a block data input stream will issue read calls corresponding to the sizes of the blocks (through header read ahead), this buffered stream fills buffers before flushing so the size represents the minimum block size. If you know the reader will be behind a buffered input stream, specify a block size greater than or equal to that buffer size to promote efficient read through.

Parameters:
size - minimum block size