public class FastBufferedInputStream extends MeasurableInputStream implements RepositionableStream
This class provides buffering for input streams, but it does so with
purposes and an internal logic that are radically different from the ones
adopted in BufferedInputStream. The main features follow.
There is no support for marking. All methods are unsychronized.
As an additional feature, this class implements the RepositionableStream and MeasurableStream interfaces.
An instance of this class will try to cast
the underlying byte stream to a RepositionableStream and to fetch by
reflection the FileChannel underlying the given
output stream, in this order. If either reference can be successfully
fetched, you can use position(long) to reposition the stream.
Much in the same way, an instance of this class will try to cast the
the underlying byte stream to a MeasurableStream, and if this
operation is successful, or if a FileChannel can
be detected, then position() and length() will work as expected.
Due to erratic and unpredictable behaviour of InputStream.skip(long),
which does not correspond to its specification and which Sun refuses to fix
(see bug 6222822;
don't be fooled by the “closed, fixed” label),
this class peeks at the underlying stream and if it is System.in it uses
repeated reads instead of calling InputStream.skip(long) on the underlying stream; moreover,
skips and reads are tried alternately, so to guarantee that skipping
less bytes than requested can be caused only by reaching the end of file.
This class keeps also track of the number of bytes read so far, so
to be able to implement MeasurableStream.position()
independently of underlying input stream.
This class has limited support for “reading a line” (whatever that means) from the underlying input stream. You can choose the set of line terminators that delimit lines.
Warning: Since fastutil 6.0.0, this class detects
a implementations of MeasurableStream instead of subclasses MeasurableInputStream (which is deprecated).
| Modifier and Type | Class and Description |
|---|---|
static class |
FastBufferedInputStream.LineTerminator
An enumeration of the supported line terminators.
|
| Modifier and Type | Field and Description |
|---|---|
static EnumSet<FastBufferedInputStream.LineTerminator> |
ALL_TERMINATORS
A set containing all available line terminators.
|
static int |
DEFAULT_BUFFER_SIZE
The default size of the internal buffer in bytes (8Ki).
|
| Constructor and Description |
|---|
FastBufferedInputStream(InputStream is)
Creates a new fast buffered input stream by wrapping a given input stream with a buffer of
DEFAULT_BUFFER_SIZE bytes. |
FastBufferedInputStream(InputStream is,
byte[] buffer)
Creates a new fast buffered input stream by wrapping a given input stream with a given buffer.
|
FastBufferedInputStream(InputStream is,
int bufferSize)
Creates a new fast buffered input stream by wrapping a given input stream with a given buffer size.
|
| Modifier and Type | Method and Description |
|---|---|
int |
available()
Returns an estimate of the number of bytes that can be read (or
skipped over) from this input stream without blocking by the next
invocation of a method for this input stream.
|
void |
close()
Closes this input stream and releases any system resources associated
with the stream.
|
void |
flush()
Resets the internal logic of this fast buffered input stream, clearing the buffer.
|
long |
length()
Returns the length of the underlying input stream, if it is measurable.
|
long |
position()
Returns the current stream position.
|
void |
position(long newPosition)
Sets the current stream position.
|
int |
read()
Reads the next byte of data from the input stream.
|
int |
read(byte[] b,
int offset,
int length)
Reads up to
len bytes of data from the input stream into
an array of bytes. |
int |
readLine(byte[] array)
Reads a line into the given byte array using all terminators.
|
int |
readLine(byte[] array,
EnumSet<FastBufferedInputStream.LineTerminator> terminators)
Reads a line into the given byte array.
|
int |
readLine(byte[] array,
int off,
int len)
Reads a line into the given byte-array fragment using all terminators.
|
int |
readLine(byte[] array,
int off,
int len,
EnumSet<FastBufferedInputStream.LineTerminator> terminators)
Reads a line into the given byte-array fragment.
|
void |
reset()
Deprecated.
As of
fastutil 5.0.4, replaced by flush(). The old
semantics of this method does not contradict InputStream's contract, as
the semantics of reset() is undefined if InputStream.markSupported()
returns false. On the other hand, the name was really a poor choice. |
long |
skip(long n)
Skips over and discards the given number of bytes of data from this fast buffered input stream.
|
mark, markSupported, readpublic static final int DEFAULT_BUFFER_SIZE
public static final EnumSet<FastBufferedInputStream.LineTerminator> ALL_TERMINATORS
public FastBufferedInputStream(InputStream is, byte[] buffer)
is - an input stream to wrap.buffer - a buffer of positive length.public FastBufferedInputStream(InputStream is, int bufferSize)
is - an input stream to wrap.bufferSize - the size in bytes of the internal buffer (greater than zero).public FastBufferedInputStream(InputStream is)
DEFAULT_BUFFER_SIZE bytes.is - an input stream to wrap.public int read()
throws IOException
java.io.InputStreamint 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.
read in class InputStream-1 if the end of the
stream is reached.IOException - if an I/O error occurs.public int read(byte[] b,
int offset,
int length)
throws IOException
java.io.InputStreamlen 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.
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 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.
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. The default implementation of this method blocks
until the requested amount of input data len has been read,
end of file is detected, or an exception is thrown. Subclasses are encouraged
to provide a more efficient implementation of this method.
read in class InputStreamb - the buffer into which the data is read.offset - the start offset in array b
at which the data is written.length - the maximum number of bytes to read.-1 if there is no more data because the end of
the stream has been reached.IOException - If the first byte cannot be read for any reason
other than end of file, or if the input stream has been closed, or if
some other I/O error occurs.InputStream.read()public int readLine(byte[] array)
throws IOException
array - byte array where the next line will be stored.array, or -1 at end of file.IOExceptionreadLine(byte[], int, int, EnumSet)public int readLine(byte[] array,
EnumSet<FastBufferedInputStream.LineTerminator> terminators)
throws IOException
array - byte array where the next line will be stored.terminators - a set containing the line termination sequences that we want
to consider as valid.array, or -1 at end of file.IOExceptionreadLine(byte[], int, int, EnumSet)public int readLine(byte[] array,
int off,
int len)
throws IOException
array - byte array where the next line will be stored.off - the first byte to use in array.len - the maximum number of bytes to read.array, or -1 at end of file.IOExceptionreadLine(byte[], int, int, EnumSet)public int readLine(byte[] array,
int off,
int len,
EnumSet<FastBufferedInputStream.LineTerminator> terminators)
throws IOException
Reading lines (i.e., characters) out of a byte stream is not always sensible (methods available to that purpose in old versions of Java have been mercilessly deprecated). Nonetheless, in several situations, such as when decoding network protocols or headers known to be ASCII, it is very useful to be able to read a line from a byte stream.
This method will attempt to read the next line into array starting at off,
reading at most len bytes. The read, however, will be stopped by the end of file or
when meeting a line terminator. Of course, for this operation
to be sensible the encoding of the text contained in the stream, if any, must not generate spurious
carriage returns or line feeds. Note that the termination detection uses a maximisation
criterion, so if you specify both FastBufferedInputStream.LineTerminator.CR and
FastBufferedInputStream.LineTerminator.CR_LF meeting a pair CR/LF will consider the whole pair a terminator.
Terminators are not copied into array or included in the returned count. The
returned integer can be used to check whether the line is complete: if it is smaller than
len, then more bytes might be available, but note that this method (contrarily
to read(byte[], int, int)) can legitimately return zero when len
is nonzero just because a terminator was found as the first character. Thus, the intended
usage of this method is to call it on a given array, check whether len bytes
have been read, and if so try again (possibly extending the array) until a number of read bytes
strictly smaller than len (possibly, -1) is returned.
If you need to guarantee that a full line is read, use the following idiom:
int start = off, len;
while((len = fbis.readLine(array, start, array.length - start, terminators)) == array.length - start) {
start += len;
array = ByteArrays.grow(array, array.length + 1);
}
At the end of the loop, the line will be placed in array starting at
off (inclusive) and ending at start + Math.max(len, 0) (exclusive).
array - byte array where the next line will be stored.off - the first byte to use in array.len - the maximum number of bytes to read.terminators - a set containing the line termination sequences that we want
to consider as valid.array, or -1 at end of file.
Note that the returned number will be len if no line termination sequence
specified in terminators has been met before scanning len byte,
and if also we did not meet the end of file.IOExceptionpublic void position(long newPosition)
throws IOException
RepositionableStreamposition in interface RepositionableStreamnewPosition - the new stream position.IOExceptionpublic long position()
throws IOException
RepositionableStreamposition in interface MeasurableStreamposition in interface RepositionableStreamIOExceptionpublic long length()
throws IOException
length in interface MeasurableStreamUnsupportedOperationException - if the underlying input stream is not measurable and
cannot provide a FileChannel.IOExceptionpublic long skip(long n)
throws IOException
As explained in the class documentation, the semantics
of InputStream.skip(long) is fatally flawed. This method provides additional semantics as follows:
it will skip the provided number of bytes, unless the end of file has been reached.
Additionally, if the underlying input stream is System.in this method will use
repeated reads instead of invoking InputStream.skip(long).
skip in class InputStreamn - the number of bytes to skip.n
only if the end of file has been reached.IOException - if the stream does not support seek,
or if some other I/O error occurs.InputStream.skip(long)public int available()
throws IOException
java.io.InputStream Note that while some implementations of InputStream will return
the total number of bytes in the stream, many will not. It is
never correct to use the return value of this method to allocate
a buffer intended to hold all data in this stream.
A subclass' implementation of this method may choose to throw an
IOException if this input stream has been closed by
invoking the InputStream.close() method.
The available method for class InputStream always
returns 0.
This method should be overridden by subclasses.
available in class InputStream0 when
it reaches the end of the input stream.IOException - if an I/O error occurs.public void close()
throws IOException
java.io.InputStream The close method of InputStream does
nothing.
close in interface Closeableclose in interface AutoCloseableclose in class InputStreamIOException - if an I/O error occurs.public void flush()
All buffering information is discarded, and the number of bytes read so far (and thus, also the current position) is adjusted to reflect this fact.
This method is mainly useful for re-reading files that have been overwritten externally.
@Deprecated public void reset()
fastutil 5.0.4, replaced by flush(). The old
semantics of this method does not contradict InputStream's contract, as
the semantics of reset() is undefined if InputStream.markSupported()
returns false. On the other hand, the name was really a poor choice.reset in class InputStreamInputStream.mark(int),
IOException