wt.util
Class BlockDataOutputStream
java.lang.Object
java.io.OutputStream
java.io.FilterOutputStream
wt.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.
Field Summary |
private boolean |
closed
|
private static boolean |
DEBUG
|
private byte[] |
header
|
private byte[] |
save
|
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.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
header
private byte[] header
save
private byte[] save
closed
private boolean closed
DEBUG
private static final boolean DEBUG
- See Also:
- Constant Field Values
BlockDataOutputStream
public BlockDataOutputStream(OutputStream output_stream)
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