Class FastBufferedInputStream
- java.lang.Object
-
- java.io.InputStream
-
- it.unimi.dsi.fastutil.io.MeasurableInputStream
-
- it.unimi.dsi.fastutil.io.FastBufferedInputStream
-
- All Implemented Interfaces:
MeasurableStream,RepositionableStream,Closeable,AutoCloseable
public class FastBufferedInputStream extends MeasurableInputStream implements RepositionableStream
Lightweight, unsynchronized, aligned input stream buffering class with true skipping, measurability, repositionability and line reading support.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
fastutil6.0.0, this class detects a implementations ofMeasurableStreaminstead of subclassesMeasurableInputStream(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 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(InputStream is)Creates a new fast buffered input stream by wrapping a given input stream with a buffer ofDEFAULT_BUFFER_SIZEbytes.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.
-
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, EnumSet<FastBufferedInputStream.LineTerminator> terminators)Reads a line into the given byte-array fragment.intreadLine(byte[] array, EnumSet<FastBufferedInputStream.LineTerminator> terminators)Reads a line into the given byte array.voidreset()Deprecated.As offastutil5.0.4, replaced byflush().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, transferTo
-
-
-
-
Field Detail
-
DEFAULT_BUFFER_SIZE
public static final int DEFAULT_BUFFER_SIZE
The default size of the internal buffer in bytes (8Ki).- See Also:
- Constant Field Values
-
ALL_TERMINATORS
public static final EnumSet<FastBufferedInputStream.LineTerminator> ALL_TERMINATORS
A set containing all available line terminators.
-
-
Constructor Detail
-
FastBufferedInputStream
public FastBufferedInputStream(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(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(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 Detail
-
read
public int read() throws IOException- Specified by:
readin classInputStream- Throws:
IOException
-
read
public int read(byte[] b, int offset, int length) throws IOException- Overrides:
readin classInputStream- Throws:
IOException
-
readLine
public int readLine(byte[] array) throws 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:
IOException- See Also:
readLine(byte[], int, int, EnumSet)
-
readLine
public int readLine(byte[] array, EnumSet<FastBufferedInputStream.LineTerminator> terminators) throws 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:
IOException- See Also:
readLine(byte[], int, int, EnumSet)
-
readLine
public int readLine(byte[] array, int off, int len) throws 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:
IOException- See Also:
readLine(byte[], int, int, EnumSet)
-
readLine
public int readLine(byte[] array, int off, int len, EnumSet<FastBufferedInputStream.LineTerminator> terminators) throws 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:
IOException
-
position
public void position(long newPosition) throws IOExceptionDescription copied from interface:RepositionableStreamSets the current stream position.- Specified by:
positionin interfaceRepositionableStream- Parameters:
newPosition- the new stream position.- Throws:
IOException
-
position
public long position() throws IOExceptionDescription copied from interface:RepositionableStreamReturns the current stream position.- Specified by:
positionin interfaceMeasurableStream- Specified by:
positionin interfaceRepositionableStream- Returns:
- the current stream position.
- Throws:
IOException
-
length
public long length() throws 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:
UnsupportedOperationException- if the underlying input stream is not measurable and cannot provide aFileChannel.IOException
-
skip
public long skip(long n) throws 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 classInputStream- 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:
IOException- See Also:
InputStream.skip(long)
-
available
public int available() throws IOException- Overrides:
availablein classInputStream- Throws:
IOException
-
close
public void close() throws IOException- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Overrides:
closein classInputStream- Throws:
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.As offastutil5.0.4, replaced byflush(). The old semantics of this method does not contradictInputStream's contract, as the semantics ofreset()is undefined ifInputStream.markSupported()returns false. On the other hand, the name was really a poor choice.Resets the internal logic of this fast buffered input stream.- Overrides:
resetin classInputStream
-
-