java.io
Class ObjectInputStream.BlockDataInputStream

java.lang.Object
  extended byjava.io.InputStream
      extended byjava.io.ObjectInputStream.BlockDataInputStream
All Implemented Interfaces:
DataInput
Enclosing class:
ObjectInputStream

private class ObjectInputStream.BlockDataInputStream
extends InputStream
implements DataInput

Input stream with two modes: in default mode, inputs data written in the same format as DataOutputStream; in "block data" mode, inputs data bracketed by block data markers (see object serialization specification for details). Buffering depends on block data mode: when in default mode, no data is buffered in advance; when in block data mode, all data for the current data block is read in at once (and buffered).


Field Summary
private  boolean blkmode
          block data mode
private  byte[] buf
          buffer for reading general/block data
private  char[] cbuf
          char buffer for fast string reads
private static int CHAR_BUF_SIZE
          (tunable) length of char buffer (for reading strings)
private  DataInputStream din
          loopback stream (for data reads that span data blocks)
private  int end
          end offset of valid data in buf, or -1 if no more block data
private  byte[] hbuf
          buffer for reading block data headers
private static int HEADER_BLOCKED
          readBlockHeader() return value indicating header read may block
private  ObjectInputStream.PeekInputStream in
          underlying stream (wrapped in peekable filter stream)
private static int MAX_BLOCK_SIZE
          maximum data block length
private static int MAX_HEADER_SIZE
          maximum data block header length
private  int pos
          current offset into buf
private  int unread
          number of bytes in current block yet to be read from stream
 
Fields inherited from class java.io.InputStream
 
Constructor Summary
(package private) ObjectInputStream.BlockDataInputStream(InputStream in)
          Creates new BlockDataInputStream on top of given underlying stream.
 
Method Summary
 int available()
          Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream.
 void close()
          Closes this input stream and releases any system resources associated with the stream.
(package private)  int currentBlockRemaining()
          If in block data mode, returns the number of unconsumed bytes remaining in the current data block.
(package private)  boolean getBlockDataMode()
          Returns true if the stream is currently in block data mode, false otherwise.
(package private)  int peek()
          Peeks at (but does not consume) and returns the next byte value in the stream, or -1 if the end of the stream/block data (if in block data mode) has been reached.
(package private)  byte peekByte()
          Peeks at (but does not consume) and returns the next byte value in the stream, or throws EOFException if end of stream/block data has been reached.
 int read()
          Reads the next byte of data from the input stream.
 int read(byte[] b, int off, int len)
          Reads up to len bytes of data from the input stream into an array of bytes.
(package private)  int read(byte[] b, int off, int len, boolean copy)
          Attempts to read len bytes into byte array b at offset off.
private  int readBlockHeader(boolean canBlock)
          Attempts to read in the next block data header (if any).
 boolean readBoolean()
          Reads one input byte and returns true if that byte is nonzero, false if that byte is zero.
(package private)  void readBooleans(boolean[] v, int off, int len)
           
 byte readByte()
          Reads and returns one input byte.
 char readChar()
          Reads an input char and returns the char value.
(package private)  void readChars(char[] v, int off, int len)
           
 double readDouble()
          Reads eight input bytes and returns a double value.
(package private)  void readDoubles(double[] v, int off, int len)
           
 float readFloat()
          Reads four input bytes and returns a float value.
(package private)  void readFloats(float[] v, int off, int len)
           
 void readFully(byte[] b)
          Reads some bytes from an input stream and stores them into the buffer array b.
 void readFully(byte[] b, int off, int len)
          Reads len bytes from an input stream.
 void readFully(byte[] b, int off, int len, boolean copy)
           
 int readInt()
          Reads four input bytes and returns an int value.
(package private)  void readInts(int[] v, int off, int len)
           
 String readLine()
          Reads the next line of text from the input stream.
 long readLong()
          Reads eight input bytes and returns a long value.
(package private)  void readLongs(long[] v, int off, int len)
           
(package private)  String readLongUTF()
          Reads in string written in "long" UTF format.
 short readShort()
          Reads two input bytes and returns a short value.
(package private)  void readShorts(short[] v, int off, int len)
           
 int readUnsignedByte()
          Reads one input byte, zero-extends it to type int, and returns the result, which is therefore in the range 0 through 255.
 int readUnsignedShort()
          Reads two input bytes and returns an int value in the range 0 through 65535.
 String readUTF()
          Reads in a string that has been encoded using a modified UTF-8 format.
private  String readUTFBody(long utflen)
          Reads in the "body" (i.e., the UTF representation minus the 2-byte or 8-byte length header) of a UTF encoding, which occupies the next utflen bytes.
private  int readUTFChar(StringBuffer sbuf, long utflen)
          Reads in single UTF-encoded character one byte at a time, appends the character to sbuf, and returns the number of bytes consumed.
private  long readUTFSpan(StringBuffer sbuf, long utflen)
          Reads span of UTF-encoded characters out of internal buffer (starting at offset pos and ending at or before offset end), consuming no more than utflen bytes.
private  void refill()
          Refills internal buffer buf with block data.
(package private)  boolean setBlockDataMode(boolean newmode)
          Sets block data mode to the given mode (true == on, false == off) and returns the previous mode value.
 long skip(long len)
          Skips over and discards n bytes of data from this input stream.
(package private)  void skipBlockData()
          If in block data mode, skips to the end of the current group of data blocks (but does not unset block data mode).
 int skipBytes(int n)
          Makes an attempt to skip over n bytes of data from the input stream, discarding the skipped bytes.
 
Methods inherited from class java.io.InputStream
mark, markSupported, read, reset
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

MAX_BLOCK_SIZE

private static final int MAX_BLOCK_SIZE
maximum data block length

See Also:
Constant Field Values

MAX_HEADER_SIZE

private static final int MAX_HEADER_SIZE
maximum data block header length

See Also:
Constant Field Values

CHAR_BUF_SIZE

private static final int CHAR_BUF_SIZE
(tunable) length of char buffer (for reading strings)

See Also:
Constant Field Values

HEADER_BLOCKED

private static final int HEADER_BLOCKED
readBlockHeader() return value indicating header read may block

See Also:
Constant Field Values

buf

private final byte[] buf
buffer for reading general/block data


hbuf

private final byte[] hbuf
buffer for reading block data headers


cbuf

private final char[] cbuf
char buffer for fast string reads


blkmode

private boolean blkmode
block data mode


pos

private int pos
current offset into buf


end

private int end
end offset of valid data in buf, or -1 if no more block data


unread

private int unread
number of bytes in current block yet to be read from stream


in

private final ObjectInputStream.PeekInputStream in
underlying stream (wrapped in peekable filter stream)


din

private final DataInputStream din
loopback stream (for data reads that span data blocks)

Constructor Detail

ObjectInputStream.BlockDataInputStream

ObjectInputStream.BlockDataInputStream(InputStream in)
Creates new BlockDataInputStream on top of given underlying stream. Block data mode is turned off by default.

Method Detail

setBlockDataMode

boolean setBlockDataMode(boolean newmode)
                   throws IOException
Sets block data mode to the given mode (true == on, false == off) and returns the previous mode value. If the new mode is the same as the old mode, no action is taken. Throws IllegalStateException if block data mode is being switched from on to off while unconsumed block data is still present in the stream.

Throws:
IOException

getBlockDataMode

boolean getBlockDataMode()
Returns true if the stream is currently in block data mode, false otherwise.


skipBlockData

void skipBlockData()
             throws IOException
If in block data mode, skips to the end of the current group of data blocks (but does not unset block data mode). If not in block data mode, throws an IllegalStateException.

Throws:
IOException

readBlockHeader

private int readBlockHeader(boolean canBlock)
                     throws IOException
Attempts to read in the next block data header (if any). If canBlock is false and a full header cannot be read without possibly blocking, returns HEADER_BLOCKED, else if the next element in the stream is a block data header, returns the block data length specified by the header, else returns -1.

Throws:
IOException

refill

private void refill()
             throws IOException
Refills internal buffer buf with block data. Any data in buf at the time of the call is considered consumed. Sets the pos, end, and unread fields to reflect the new amount of available block data; if the next element in the stream is not a data block, sets pos and unread to 0 and end to -1.

Throws:
IOException

currentBlockRemaining

int currentBlockRemaining()
If in block data mode, returns the number of unconsumed bytes remaining in the current data block. If not in block data mode, throws an IllegalStateException.


peek

int peek()
   throws IOException
Peeks at (but does not consume) and returns the next byte value in the stream, or -1 if the end of the stream/block data (if in block data mode) has been reached.

Throws:
IOException

peekByte

byte peekByte()
        throws IOException
Peeks at (but does not consume) and returns the next byte value in the stream, or throws EOFException if end of stream/block data has been reached.

Throws:
IOException

read

public int read()
         throws IOException
Description copied from class: InputStream
Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

A subclass must provide an implementation of this method.

Specified by:
read in class InputStream
Returns:
the next byte of data, or -1 if the end of the stream is reached.
Throws:
IOException - if an I/O error occurs.

read

public int read(byte[] b,
                int off,
                int len)
         throws IOException
Description copied from class: InputStream
Reads up to len bytes of data from the input stream into an array of bytes. An attempt is made to read as many as len bytes, but a smaller number may be read, possibly zero. The number of bytes actually read is returned as an integer.

This method blocks until input data is available, end of file is detected, or an exception is thrown.

If b is null, a NullPointerException is thrown.

If off is negative, or len is negative, or off+len is greater than the length of the array b, then an IndexOutOfBoundsException is thrown.

If len is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte. If no byte is available because the stream is at end of file, the value -1 is returned; otherwise, at least one byte is read and stored into b.

The first byte read is stored into element b[off], the next one into b[off+1], and so on. The number of bytes read is, at most, equal to len. Let k be the number of bytes actually read; these bytes will be stored in elements b[off] through b[off+k-1], leaving elements b[off+k] through b[off+len-1] unaffected.

In every case, elements b[0] through b[off] and elements b[off+len] through b[b.length-1] are unaffected.

If the first byte cannot be read for any reason other than end of file, then an IOException is thrown. In particular, an IOException is thrown if the input stream has been closed.

The read(b, off, len) method for class InputStream simply calls the method read() repeatedly. If the first such call results in an IOException, that exception is returned from the call to the read(b, off, len) method. If any subsequent call to read() results in a IOException, the exception is caught and treated as if it were end of file; the bytes read up to that point are stored into b and the number of bytes read before the exception occurred is returned. Subclasses are encouraged to provide a more efficient implementation of this method.

Overrides:
read in class InputStream
Parameters:
b - the buffer into which the data is read.
off - the start offset in array b at which the data is written.
len - the maximum number of bytes to read.
Returns:
the total number of bytes read into the buffer, or -1 if there is no more data because the end of the stream has been reached.
Throws:
IOException - if an I/O error occurs.
See Also:
InputStream.read()

skip

public long skip(long len)
          throws IOException
Description copied from class: InputStream
Skips over and discards n bytes of data from this input stream. The skip method may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly 0. This may result from any of a number of conditions; reaching end of file before n bytes have been skipped is only one possibility. The actual number of bytes skipped is returned. If n is negative, no bytes are skipped.

The skip method of InputStream creates a byte array and then repeatedly reads into it until n bytes have been read or the end of the stream has been reached. Subclasses are encouraged to provide a more efficient implementation of this method.

Overrides:
skip in class InputStream
Parameters:
len - the number of bytes to be skipped.
Returns:
the actual number of bytes skipped.
Throws:
IOException - if an I/O error occurs.

available

public int available()
              throws IOException
Description copied from class: InputStream
Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream. The next caller might be the same thread or or another thread.

The available method for class InputStream always returns 0.

This method should be overridden by subclasses.

Overrides:
available in class InputStream
Returns:
the number of bytes that can be read from this input stream without blocking.
Throws:
IOException - if an I/O error occurs.

close

public void close()
           throws IOException
Description copied from class: InputStream
Closes this input stream and releases any system resources associated with the stream.

The close method of InputStream does nothing.

Overrides:
close in class InputStream
Throws:
IOException - if an I/O error occurs.

read

int read(byte[] b,
         int off,
         int len,
         boolean copy)
   throws IOException
Attempts to read len bytes into byte array b at offset off. Returns the number of bytes read, or -1 if the end of stream/block data has been reached. If copy is true, reads values into an intermediate buffer before copying them to b (to avoid exposing a reference to b).

Throws:
IOException

readFully

public void readFully(byte[] b)
               throws IOException
Description copied from interface: DataInput
Reads some bytes from an input stream and stores them into the buffer array b. The number of bytes read is equal to the length of b.

This method blocks until one of the following conditions occurs:

If b is null, a NullPointerException is thrown. If b.length is zero, then no bytes are read. Otherwise, the first byte read is stored into element b[0], the next one into b[1], and so on. If an exception is thrown from this method, then it may be that some but not all bytes of b have been updated with data from the input stream.

Specified by:
readFully in interface DataInput
Parameters:
b - the buffer into which the data is read.
Throws:
IOException - if an I/O error occurs.

readFully

public void readFully(byte[] b,
                      int off,
                      int len)
               throws IOException
Description copied from interface: DataInput
Reads len bytes from an input stream.

This method blocks until one of the following conditions occurs:

If b is null, a NullPointerException is thrown. If off is negative, or len is negative, or off+len is greater than the length of the array b, then an IndexOutOfBoundsException is thrown. If len is zero, then no bytes are read. Otherwise, the first byte read is stored into element b[off], the next one into b[off+1], and so on. The number of bytes read is, at most, equal to len.

Specified by:
readFully in interface DataInput
Parameters:
b - the buffer into which the data is read.
off - an int specifying the offset into the data.
len - an int specifying the number of bytes to read.
Throws:
IOException - if an I/O error occurs.

readFully

public void readFully(byte[] b,
                      int off,
                      int len,
                      boolean copy)
               throws IOException
Throws:
IOException

skipBytes

public int skipBytes(int n)
              throws IOException
Description copied from interface: DataInput
Makes an attempt to skip over n bytes of data from the input stream, discarding the skipped bytes. However, it may skip over some smaller number of bytes, possibly zero. This may result from any of a number of conditions; reaching end of file before n bytes have been skipped is only one possibility. This method never throws an EOFException. The actual number of bytes skipped is returned.

Specified by:
skipBytes in interface DataInput
Parameters:
n - the number of bytes to be skipped.
Returns:
the number of bytes actually skipped.
Throws:
IOException - if an I/O error occurs.

readBoolean

public boolean readBoolean()
                    throws IOException
Description copied from interface: DataInput
Reads one input byte and returns true if that byte is nonzero, false if that byte is zero. This method is suitable for reading the byte written by the writeBoolean method of interface DataOutput.

Specified by:
readBoolean in interface DataInput
Returns:
the boolean value read.
Throws:
IOException - if an I/O error occurs.

readByte

public byte readByte()
              throws IOException
Description copied from interface: DataInput
Reads and returns one input byte. The byte is treated as a signed value in the range -128 through 127, inclusive. This method is suitable for reading the byte written by the writeByte method of interface DataOutput.

Specified by:
readByte in interface DataInput
Returns:
the 8-bit value read.
Throws:
IOException - if an I/O error occurs.

readUnsignedByte

public int readUnsignedByte()
                     throws IOException
Description copied from interface: DataInput
Reads one input byte, zero-extends it to type int, and returns the result, which is therefore in the range 0 through 255. This method is suitable for reading the byte written by the writeByte method of interface DataOutput if the argument to writeByte was intended to be a value in the range 0 through 255.

Specified by:
readUnsignedByte in interface DataInput
Returns:
the unsigned 8-bit value read.
Throws:
IOException - if an I/O error occurs.

readChar

public char readChar()
              throws IOException
Description copied from interface: DataInput
Reads an input char and returns the char value. A Unicode char is made up of two bytes. Let a be the first byte read and b be the second byte. The value returned is:

(char)((a << 8) | (b & 0xff))
 
This method is suitable for reading bytes written by the writeChar method of interface DataOutput.

Specified by:
readChar in interface DataInput
Returns:
the Unicode char read.
Throws:
IOException - if an I/O error occurs.

readShort

public short readShort()
                throws IOException
Description copied from interface: DataInput
Reads two input bytes and returns a short value. Let a be the first byte read and b be the second byte. The value returned is:

(short)((a << 8) * | (b & 0xff))
 
This method is suitable for reading the bytes written by the writeShort method of interface DataOutput.

Specified by:
readShort in interface DataInput
Returns:
the 16-bit value read.
Throws:
IOException - if an I/O error occurs.

readUnsignedShort

public int readUnsignedShort()
                      throws IOException
Description copied from interface: DataInput
Reads two input bytes and returns an int value in the range 0 through 65535. Let a be the first byte read and b be the second byte. The value returned is:

(((a & 0xff) << 8) | (b & 0xff))
 
This method is suitable for reading the bytes written by the writeShort method of interface DataOutput if the argument to writeShort was intended to be a value in the range 0 through 65535.

Specified by:
readUnsignedShort in interface DataInput
Returns:
the unsigned 16-bit value read.
Throws:
IOException - if an I/O error occurs.

readInt

public int readInt()
            throws IOException
Description copied from interface: DataInput
Reads four input bytes and returns an int value. Let a be the first byte read, b be the second byte, c be the third byte, and d be the fourth byte. The value returned is:

 
 (((a & 0xff) << 24) | ((b & 0xff) << 16) |
  ((c & 0xff) << 8) | (d & 0xff))
 
This method is suitable for reading bytes written by the writeInt method of interface DataOutput.

Specified by:
readInt in interface DataInput
Returns:
the int value read.
Throws:
IOException - if an I/O error occurs.

readFloat

public float readFloat()
                throws IOException
Description copied from interface: DataInput
Reads four input bytes and returns a float value. It does this by first constructing an int value in exactly the manner of the readInt method, then converting this int value to a float in exactly the manner of the method Float.intBitsToFloat. This method is suitable for reading bytes written by the writeFloat method of interface DataOutput.

Specified by:
readFloat in interface DataInput
Returns:
the float value read.
Throws:
IOException - if an I/O error occurs.

readLong

public long readLong()
              throws IOException
Description copied from interface: DataInput
Reads eight input bytes and returns a long value. Let a be the first byte read, b be the second byte, c be the third byte, d be the fourth byte, e be the fifth byte, f be the sixth byte, g be the seventh byte, and h be the eighth byte. The value returned is:

 
 (((long)(a & 0xff) << 56) |
  ((long)(b & 0xff) << 48) |
  ((long)(c & 0xff) << 40) |
  ((long)(d & 0xff) << 32) |
  ((long)(e & 0xff) << 24) |
  ((long)(f & 0xff) << 16) |
  ((long)(g & 0xff) <<  8) |
  ((long)(h & 0xff)))
 

This method is suitable for reading bytes written by the writeLong method of interface DataOutput.

Specified by:
readLong in interface DataInput
Returns:
the long value read.
Throws:
IOException - if an I/O error occurs.

readDouble

public double readDouble()
                  throws IOException
Description copied from interface: DataInput
Reads eight input bytes and returns a double value. It does this by first constructing a long value in exactly the manner of the readlong method, then converting this long value to a double in exactly the manner of the method Double.longBitsToDouble. This method is suitable for reading bytes written by the writeDouble method of interface DataOutput.

Specified by:
readDouble in interface DataInput
Returns:
the double value read.
Throws:
IOException - if an I/O error occurs.

readUTF

public String readUTF()
               throws IOException
Description copied from interface: DataInput
Reads in a string that has been encoded using a modified UTF-8 format. The general contract of readUTF is that it reads a representation of a Unicode character string encoded in Java modified UTF-8 format; this string of characters is then returned as a String.

First, two bytes are read and used to construct an unsigned 16-bit integer in exactly the manner of the readUnsignedShort method . This integer value is called the UTF length and specifies the number of additional bytes to be read. These bytes are then converted to characters by considering them in groups. The length of each group is computed from the value of the first byte of the group. The byte following a group, if any, is the first byte of the next group.

If the first byte of a group matches the bit pattern 0xxxxxxx (where x means "may be 0 or 1"), then the group consists of just that byte. The byte is zero-extended to form a character.

If the first byte of a group matches the bit pattern 110xxxxx, then the group consists of that byte a and a second byte b. If there is no byte b (because byte a was the last of the bytes to be read), or if byte b does not match the bit pattern 10xxxxxx, then a UTFDataFormatException is thrown. Otherwise, the group is converted to the character:

(char)(((a& 0x1F) << 6) | (b & 0x3F))
 
If the first byte of a group matches the bit pattern 1110xxxx, then the group consists of that byte a and two more bytes b and c. If there is no byte c (because byte a was one of the last two of the bytes to be read), or either byte b or byte c does not match the bit pattern 10xxxxxx, then a UTFDataFormatException is thrown. Otherwise, the group is converted to the character:


 (char)(((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F))
 
If the first byte of a group matches the pattern 1111xxxx or the pattern 10xxxxxx, then a UTFDataFormatException is thrown.

If end of file is encountered at any time during this entire process, then an EOFException is thrown.

After every group has been converted to a character by this process, the characters are gathered, in the same order in which their corresponding groups were read from the input stream, to form a String, which is returned.

The writeUTF method of interface DataOutput may be used to write data that is suitable for reading by this method.

Specified by:
readUTF in interface DataInput
Returns:
a Unicode string.
Throws:
IOException - if an I/O error occurs.

readLine

public String readLine()
                throws IOException
Description copied from interface: DataInput
Reads the next line of text from the input stream. It reads successive bytes, converting each byte separately into a character, until it encounters a line terminator or end of file; the characters read are then returned as a String. Note that because this method processes bytes, it does not support input of the full Unicode character set.

If end of file is encountered before even one byte can be read, then null is returned. Otherwise, each byte that is read is converted to type char by zero-extension. If the character '\n' is encountered, it is discarded and reading ceases. If the character '\r' is encountered, it is discarded and, if the following byte converts to the character '\n', then that is discarded also; reading then ceases. If end of file is encountered before either of the characters '\n' and '\r' is encountered, reading ceases. Once reading has ceased, a String is returned that contains all the characters read and not discarded, taken in order. Note that every character in this string will have a value less than \u0100, that is, (char)256.

Specified by:
readLine in interface DataInput
Returns:
the next line of text from the input stream, or null if the end of file is encountered before a byte can be read.
Throws:
IOException - if an I/O error occurs.

readBooleans

void readBooleans(boolean[] v,
                  int off,
                  int len)
            throws IOException
Throws:
IOException

readChars

void readChars(char[] v,
               int off,
               int len)
         throws IOException
Throws:
IOException

readShorts

void readShorts(short[] v,
                int off,
                int len)
          throws IOException
Throws:
IOException

readInts

void readInts(int[] v,
              int off,
              int len)
        throws IOException
Throws:
IOException

readFloats

void readFloats(float[] v,
                int off,
                int len)
          throws IOException
Throws:
IOException

readLongs

void readLongs(long[] v,
               int off,
               int len)
         throws IOException
Throws:
IOException

readDoubles

void readDoubles(double[] v,
                 int off,
                 int len)
           throws IOException
Throws:
IOException

readLongUTF

String readLongUTF()
             throws IOException
Reads in string written in "long" UTF format. "Long" UTF format is identical to standard UTF, except that it uses an 8 byte header (instead of the standard 2 bytes) to convey the UTF encoding length.

Throws:
IOException

readUTFBody

private String readUTFBody(long utflen)
                    throws IOException
Reads in the "body" (i.e., the UTF representation minus the 2-byte or 8-byte length header) of a UTF encoding, which occupies the next utflen bytes.

Throws:
IOException

readUTFSpan

private long readUTFSpan(StringBuffer sbuf,
                         long utflen)
                  throws IOException
Reads span of UTF-encoded characters out of internal buffer (starting at offset pos and ending at or before offset end), consuming no more than utflen bytes. Appends read characters to sbuf. Returns the number of bytes consumed.

Throws:
IOException

readUTFChar

private int readUTFChar(StringBuffer sbuf,
                        long utflen)
                 throws IOException
Reads in single UTF-encoded character one byte at a time, appends the character to sbuf, and returns the number of bytes consumed. This method is used when reading in UTF strings written in block data mode to handle UTF-encoded characters which (potentially) straddle block-data boundaries.

Throws:
IOException