Class InspectableBufferedInputStream
- All Implemented Interfaces:
MeasurableStream
,Closeable
,AutoCloseable
public class InspectableBufferedInputStream extends MeasurableInputStream
Stream behaviour
In the following description, we let K0 be the buffer size, K be the number of bytes read from the underlying stream, P be the index of the next byte that will be returned by this stream (indices start from 0) and L be the number of bytes that will be required. Note that P≤K, and equality holds if this stream was never rewound; otherwise, P may be smaller than K (and, in particular, it will be zero just after a rewind).
When the stream is connected, up to K0 bytes are read and stored in the buffer; after that, the buffer itself becomes available for inspection. Of course, K is set to the number of bytes actually read, whereas P=0.
Upon reading, as long as P+L-1<K, no byte must actually be read from the input stream. Otherwise, up to P+L-K bytes are read from the input stream and stored onto the overflow file before returning them to the user.
Connecting and disposing
Objects of this class are reusable by design. At any moment, they may be in one of three states: connected, ready, disposed:
- connected: this stream is connected to an underlying input stream, and has an overflow file open and partially filled; notice that, since the overflow file is reused, the file itself may be larger than the number of bytes written in it;
- ready: this stream is not connected to any underlying input stream, but it has an overflow file (not open, but ready to be used); notice that, since the overflow file is reused, the file itself may be nonempty;
- disposed: this stream cannot be used anymore: its resources are disposed and, in particular, its overflow file was actually deleted.
At creation, this stream is ready; it can be connected using connect(InputStream)
. At any time,
it can become ready again by a call to close()
. The close()
method does not truncate the
overflow file; if the user wants to truncate the file, it can do so by calling truncate(long)
after
closing. The dispose()
method makes this stream disposed; this method is called on finalization.
Buffering
This class provides no form of buffering except for the memory buffer described above. Users should consider providing
a buffered underlying input stream, or wrapping instances of this class by a FastBufferedInputStream
: the
former would be appropriate only for those cases when fillAndRewind()
is not used; the latter can make accesses more efficient,
only if the size of the underlying input stream is often much larger than the buffer size.
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
InspectableBufferedInputStream.State
The possible states of this stream, as explained above. -
Field Summary
Fields Modifier and Type Field Description byte[]
buffer
The buffer.static boolean
DEBUG
static int
DEFAULT_BUFFER_SIZE
The default buffer size (64KiB).int
inspectable
The number of bytes read in the buffer, when connected.static Logger
LOGGER
static int
OVERFLOW_FILE_RANDOM_PATH_ELEMENTS
The number of path elements for the hierarchical overflow file (seeUtil.createHierarchicalTempFile(File, int, String, String)
).File
overflowFile
The overflow file used by this stream: it is created at construction time, and deleted ondispose()
, finalization, or exit. -
Constructor Summary
Constructors Constructor Description InspectableBufferedInputStream()
Creates a new ready stream with default buffer size, and using default temporary directory for the overflow file.InspectableBufferedInputStream(int bufferSize)
Creates a new ready stream using default temporary directory for the overflow file.InspectableBufferedInputStream(int bufferSize, File overflowFileDir)
Creates a new ready stream. -
Method Summary
Modifier and Type Method Description int
available()
void
close()
Makes this stream ready.void
connect(InputStream underlying)
Connects to a given input stream, and fills the buffer accordingly.void
dispose()
Disposes this stream, deleting the overflow file and nulling the buffer.void
fill()
Reads fully the underlying input stream.void
fill(long limit)
Reads the underlying input stream up to a given limit.void
fillAndRewind()
Reads fully the underlying input stream and rewinds.protected void
finalize()
long
length()
Returns the overall length of this input stream.long
overflowLength()
Returns the current length of the overflow file.long
position()
int
read()
int
read(byte[] b)
int
read(byte[] b, int offset, int length)
long
readBytes()
The number of bytes read so far from the underlying stream.void
rewind()
Rewinds this stream.long
skip(long n)
void
truncate(long size)
Truncates the overflow file to a given size.Methods inherited from class java.io.InputStream
mark, markSupported, nullInputStream, readAllBytes, readNBytes, readNBytes, reset, skipNBytes, transferTo
-
Field Details
-
LOGGER
-
DEBUG
public static final boolean DEBUG- See Also:
- Constant Field Values
-
OVERFLOW_FILE_RANDOM_PATH_ELEMENTS
public static final int OVERFLOW_FILE_RANDOM_PATH_ELEMENTSThe number of path elements for the hierarchical overflow file (seeUtil.createHierarchicalTempFile(File, int, String, String)
).- See Also:
- Constant Field Values
-
DEFAULT_BUFFER_SIZE
public static final int DEFAULT_BUFFER_SIZEThe default buffer size (64KiB).- See Also:
- Constant Field Values
-
buffer
public byte[] bufferThe buffer. When connected, it is filled with the first portion of the underlying input stream (read at connection). The buffer is available for inspection, but users should not modify its content; the number of bytes actually available isinspectable
. -
inspectable
public int inspectableThe number of bytes read in the buffer, when connected. It is the minimum betweenbuffer.size
and the length of the underlying stream. -
overflowFile
The overflow file used by this stream: it is created at construction time, and deleted ondispose()
, finalization, or exit.
-
-
Constructor Details
-
InspectableBufferedInputStream
Creates a new ready stream.- Parameters:
bufferSize
- the buffer size, in bytes.overflowFileDir
- the directory where the overflow file should be created, ornull
for the default temporary directory.- Throws:
IOException
- if some exception occurs during creation.
-
InspectableBufferedInputStream
Creates a new ready stream using default temporary directory for the overflow file.- Parameters:
bufferSize
- the buffer size, in bytes.- Throws:
IOException
- if some exception occurs during creation.
-
InspectableBufferedInputStream
Creates a new ready stream with default buffer size, and using default temporary directory for the overflow file.- Throws:
IOException
- if some exception occurs during creation.
-
-
Method Details
-
connect
Connects to a given input stream, and fills the buffer accordingly. Can only be called on a non-disposed stream.- Parameters:
underlying
- the underlying input stream to which we should connect.- Throws:
IOException
- if some exception occurs while reading
-
truncate
Truncates the overflow file to a given size. Can only be called when this stream is ready.- Parameters:
size
- the new size; the final size is guaranteed to be no more than this.- Throws:
IOException
- if some exception occurs while truncating the fileFileNotFoundException
-
readBytes
public long readBytes()The number of bytes read so far from the underlying stream.- Returns:
- the number of bytes read so far from the underlying stream.
-
dispose
Disposes this stream, deleting the overflow file and nulling the buffer. After this, the stream is unusable.- Throws:
IOException
-
finalize
-
close
Makes this stream ready. Can only be called on a non-disposed stream. If the stream is ready, it does nothing. If the stream is connected, it closes the underlying stream, making this stream ready for a newconnection
or to bedisposed
.- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
- Overrides:
close
in classInputStream
- Throws:
IOException
-
rewind
Rewinds this stream. Can only be called on a connected stream.- Throws:
IOException
-
available
- Overrides:
available
in classInputStream
- Throws:
IOException
-
read
- Overrides:
read
in classInputStream
- Throws:
IOException
-
read
- Overrides:
read
in classInputStream
- Throws:
IOException
-
skip
- Overrides:
skip
in classInputStream
- Throws:
IOException
-
read
- Specified by:
read
in classInputStream
- Throws:
IOException
-
overflowLength
public long overflowLength()Returns the current length of the overflow file.- Returns:
- the length of the overflow file.
-
fill
Reads the underlying input stream up to a given limit.- Parameters:
limit
- the maximum number of bytes to be read, except for the memory buffer. More precisely, up toMath.max(buffer.length,limit)
bytes are read (because the buffer is filled at connection).- Throws:
IOException
-
fill
Reads fully the underlying input stream.- Throws:
IOException
- See Also:
fill(long)
-
fillAndRewind
Reads fully the underlying input stream and rewinds.- Throws:
IOException
- See Also:
fill()
,rewind()
-
length
public long length()Returns the overall length of this input stream. This method calls it with argumentLong.MAX_VALUE
.- Throws:
RuntimeException
- wrapping anIOException
if the call tofill(long)
does.
-
position
public long position()
-