Class FastBufferedInputStream
- All Implemented Interfaces:
MeasurableStream,RepositionableStream,java.io.Closeable,java.lang.AutoCloseable
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
RepositionableStreamandMeasurableStreaminterfaces. An instance of this class will try to cast the underlying byte stream to aRepositionableStreamand to fetch by reflection theFileChannelunderlying the given output stream, in this order. If either reference can be successfully fetched, you can useposition(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 aMeasurableStream, and if this operation is successful, or if aFileChannelcan be detected, thenposition()andlength()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 isSystem.init uses repeated reads instead of callingInputStream.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).
- Since:
- 4.4
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classFastBufferedInputStream.LineTerminatorAn enumeration of the supported line terminators. -
Field Summary
Fields Modifier and Type Field Description static java.util.EnumSet<FastBufferedInputStream.LineTerminator>ALL_TERMINATORSA set containing all available line terminators.static intDEFAULT_BUFFER_SIZEThe default size of the internal buffer in bytes (8Ki). -
Constructor Summary
Constructors Constructor Description FastBufferedInputStream(java.io.InputStream is)Creates a new fast buffered input stream by wrapping a given input stream with a buffer ofDEFAULT_BUFFER_SIZEbytes.FastBufferedInputStream(java.io.InputStream is, byte[] buffer)Creates a new fast buffered input stream by wrapping a given input stream with a given buffer.FastBufferedInputStream(java.io.InputStream is, int bufferSize)Creates a new fast buffered input stream by wrapping a given input stream with a given buffer size. -
Method Summary
Modifier and Type Method Description intavailable()voidclose()voidflush()Resets the internal logic of this fast buffered input stream, clearing the buffer.longlength()Returns the length of the underlying input stream, if it is measurable.longposition()Returns the current stream position.voidposition(long newPosition)Sets the current stream position.intread()intread(byte[] b, int offset, int length)intreadLine(byte[] array)Reads a line into the given byte array using all terminators.intreadLine(byte[] array, int off, int len)Reads a line into the given byte-array fragment using all terminators.intreadLine(byte[] array, int off, int len, java.util.EnumSet<FastBufferedInputStream.LineTerminator> terminators)Reads a line into the given byte-array fragment.intreadLine(byte[] array, java.util.EnumSet<FastBufferedInputStream.LineTerminator> terminators)Reads a line into the given byte array.voidreset()Deprecated.longskip(long n)Skips over and discards the given number of bytes of data from this fast buffered input stream.Methods inherited from class java.io.InputStream
mark, markSupported, nullInputStream, read, readAllBytes, readNBytes, readNBytes, skipNBytes, transferToMethods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Field Details
-
DEFAULT_BUFFER_SIZE
public static final int DEFAULT_BUFFER_SIZEThe default size of the internal buffer in bytes (8Ki).- See Also:
- Constant Field Values
-
ALL_TERMINATORS
A set containing all available line terminators.
-
-
Constructor Details
-
FastBufferedInputStream
public FastBufferedInputStream(java.io.InputStream is, byte[] buffer)Creates a new fast buffered input stream by wrapping a given input stream with a given buffer.- Parameters:
is- an input stream to wrap.buffer- a buffer of positive length.
-
FastBufferedInputStream
public FastBufferedInputStream(java.io.InputStream is, int bufferSize)Creates a new fast buffered input stream by wrapping a given input stream with a given buffer size.- Parameters:
is- an input stream to wrap.bufferSize- the size in bytes of the internal buffer (greater than zero).
-
FastBufferedInputStream
public FastBufferedInputStream(java.io.InputStream is)Creates a new fast buffered input stream by wrapping a given input stream with a buffer ofDEFAULT_BUFFER_SIZEbytes.- Parameters:
is- an input stream to wrap.
-
-
Method Details
-
read
public int read() throws java.io.IOException- Specified by:
readin classjava.io.InputStream- Throws:
java.io.IOException
-
read
public int read(byte[] b, int offset, int length) throws java.io.IOException- Overrides:
readin classjava.io.InputStream- Throws:
java.io.IOException
-
readLine
public int readLine(byte[] array) throws java.io.IOExceptionReads a line into the given byte array using all terminators.- Parameters:
array- byte array where the next line will be stored.- Returns:
- the number of bytes actually placed in
array, or -1 at end of file. - Throws:
java.io.IOException- See Also:
readLine(byte[], int, int, EnumSet)
-
readLine
public int readLine(byte[] array, java.util.EnumSet<FastBufferedInputStream.LineTerminator> terminators) throws java.io.IOExceptionReads a line into the given byte array.- Parameters:
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.- Returns:
- the number of bytes actually placed in
array, or -1 at end of file. - Throws:
java.io.IOException- See Also:
readLine(byte[], int, int, EnumSet)
-
readLine
public int readLine(byte[] array, int off, int len) throws java.io.IOExceptionReads a line into the given byte-array fragment using all terminators.- Parameters:
array- byte array where the next line will be stored.off- the first byte to use inarray.len- the maximum number of bytes to read.- Returns:
- the number of bytes actually placed in
array, or -1 at end of file. - Throws:
java.io.IOException- See Also:
readLine(byte[], int, int, EnumSet)
-
readLine
public int readLine(byte[] array, int off, int len, java.util.EnumSet<FastBufferedInputStream.LineTerminator> terminators) throws java.io.IOExceptionReads a line into the given byte-array fragment.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
arraystarting atoff, reading at mostlenbytes. 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 bothFastBufferedInputStream.LineTerminator.CRandFastBufferedInputStream.LineTerminator.CR_LFmeeting 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 toread(byte[], int, int)) can legitimately return zero whenlenis 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 whetherlenbytes have been read, and if so try again (possibly extending the array) until a number of read bytes strictly smaller thanlen(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
arraystarting atoff(inclusive) and ending atstart + Math.max(len, 0)(exclusive).- Parameters:
array- byte array where the next line will be stored.off- the first byte to use inarray.len- the maximum number of bytes to read.terminators- a set containing the line termination sequences that we want to consider as valid.- Returns:
- the number of bytes actually placed in
array, or -1 at end of file. Note that the returned number will belenif no line termination sequence specified interminatorshas been met before scanninglenbyte, and if also we did not meet the end of file. - Throws:
java.io.IOException
-
position
public void position(long newPosition) throws java.io.IOExceptionDescription copied from interface:RepositionableStreamSets the current stream position.- Specified by:
positionin interfaceRepositionableStream- Parameters:
newPosition- the new stream position.- Throws:
java.io.IOException
-
position
public long position() throws java.io.IOExceptionDescription copied from interface:RepositionableStreamReturns the current stream position.- Specified by:
positionin interfaceMeasurableStream- Specified by:
positionin interfaceRepositionableStream- Returns:
- the current stream position.
- Throws:
java.io.IOException
-
length
public long length() throws java.io.IOExceptionReturns the length of the underlying input stream, if it is measurable.- Specified by:
lengthin interfaceMeasurableStream- Returns:
- the length of the underlying input stream.
- Throws:
java.lang.UnsupportedOperationException- if the underlying input stream is not measurable and cannot provide aFileChannel.java.io.IOException
-
skip
public long skip(long n) throws java.io.IOExceptionSkips over and discards the given number of bytes of data from this fast buffered input stream.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.inthis method will use repeated reads instead of invokingInputStream.skip(long).- Overrides:
skipin classjava.io.InputStream- Parameters:
n- the number of bytes to skip.- Returns:
- the number of bytes actually skipped; it can be smaller than
nonly if the end of file has been reached. - Throws:
java.io.IOException- See Also:
InputStream.skip(long)
-
available
public int available() throws java.io.IOException- Overrides:
availablein classjava.io.InputStream- Throws:
java.io.IOException
-
close
public void close() throws java.io.IOException- Specified by:
closein interfacejava.lang.AutoCloseable- Specified by:
closein interfacejava.io.Closeable- Overrides:
closein classjava.io.InputStream- Throws:
java.io.IOException
-
flush
public void flush()Resets the internal logic of this fast buffered input stream, clearing the buffer.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.
-
reset
@Deprecated public void reset()Deprecated.Resets the internal logic of this fast buffered input stream.- Overrides:
resetin classjava.io.InputStream
-
fastutil5.0.4, replaced byflush().