public class MappedByteBufferInputStream extends InputStream
InputStream
implementation based on an underlying FileChannel
's memory mapped ByteBuffer
,
supporting
mark
and reset()
.
Implementation allows full memory mapped ByteBuffer
coverage via FileChannel
beyond its size limitation of Integer.MAX_VALUE
utilizing an array of ByteBuffer
slices.
Implementation further allows full random access via position()
and position(long)
and accessing the memory mapped ByteBuffer
slices directly via currentSlice()
and nextSlice()
.
Modifier and Type | Class and Description |
---|---|
static class |
MappedByteBufferInputStream.CacheMode |
static interface |
MappedByteBufferInputStream.FileResizeOp
File resize interface allowing a file to change its size,
e.g.
|
Modifier and Type | Field and Description |
---|---|
static int |
DEFAULT_SLICE_SHIFT
Default slice shift, i.e.
|
Constructor and Description |
---|
MappedByteBufferInputStream(FileChannel fileChannel)
Creates a new instance using the given
FileChannel ,
read-only mapping mode, MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD
and the DEFAULT_SLICE_SHIFT . |
MappedByteBufferInputStream(FileChannel fileChannel,
FileChannel.MapMode mmode,
MappedByteBufferInputStream.CacheMode cmode)
Creates a new instance using the given
FileChannel ,
given mapping-mode, given cache-mode and the DEFAULT_SLICE_SHIFT . |
MappedByteBufferInputStream(FileChannel fileChannel,
FileChannel.MapMode mmode,
MappedByteBufferInputStream.CacheMode cmode,
int sliceShift)
Creates a new instance using the given
FileChannel . |
Modifier and Type | Method and Description |
---|---|
int |
available()
See
remaining() for an accurate variant. |
void |
close() |
ByteBuffer |
currentSlice()
Return the mapped
ByteBuffer slice at the current position() . |
void |
flush(boolean metaData)
Similar to
OutputStream.flush() , synchronizes all mapped buffers
from local storage via MappedByteBuffer.force()
as well as the FileChannel.force(boolean) w/o metaData . |
MappedByteBufferInputStream.CacheMode |
getCacheMode()
Return the used
MappedByteBufferInputStream.CacheMode . |
MappedByteBufferOutputStream |
getOutputStream(MappedByteBufferInputStream.FileResizeOp fileResizeOp)
Returns a new MappedByteBufferOutputStream instance sharing
all resources of this input stream, including all buffer slices.
|
boolean |
getSynchronous()
Return
synchronous mode . |
long |
length()
Returns the total size in bytes of the
InputStream |
void |
mark(int readlimit) |
boolean |
markSupported() |
ByteBuffer |
nextSlice()
Return the next mapped
ByteBuffer slice from the current position() ,
implicitly setting position(long) to the start of the returned next slice,
see currentSlice() . |
void |
notifyLengthChange(long newTotalSize)
Notify this instance that the underlying
FileChannel 's size has been changed
and adjusting this instances buffer slices and states accordingly. |
long |
position()
Returns the absolute position of the
InputStream . |
MappedByteBufferInputStream |
position(long newPosition)
Sets the absolute position of the
InputStream to newPosition . |
int |
read() |
int |
read(byte[] b,
int off,
int len) |
int |
read(ByteBuffer b,
int len)
Perform similar to
read(byte[], int, int)
with ByteBuffer instead of byte array. |
long |
remaining()
Returns the number of remaining available bytes of the
InputStream ,
i.e. |
void |
reset() |
void |
setFileResizeOp(MappedByteBufferInputStream.FileResizeOp fileResizeOp) |
void |
setLength(long newTotalSize)
Resize the underlying
FileChannel 's size and adjusting this instance
via accordingly . |
void |
setSynchronous(boolean s)
Enable or disable synchronous mode.
|
long |
skip(long n) |
read
public static final int DEFAULT_SLICE_SHIFT
64bit machines
-> 30 = 1024 MiB32bit machines
-> 29 = 512 MiBIn case the default is too much of-used up address-space, one may choose other values:
public MappedByteBufferInputStream(FileChannel fileChannel, FileChannel.MapMode mmode, MappedByteBufferInputStream.CacheMode cmode, int sliceShift) throws IOException
FileChannel
.
The ByteBuffer
slices will be mapped lazily at first usage.
fileChannel
- the file channel to be mapped lazily.mmode
- the map mode, default is FileChannel.MapMode#READ_ONLY
.cmode
- the caching mode, default is MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD
.sliceShift
- the pow2 slice size, default is DEFAULT_SLICE_SHIFT
.IOException
public MappedByteBufferInputStream(FileChannel fileChannel, FileChannel.MapMode mmode, MappedByteBufferInputStream.CacheMode cmode) throws IOException
FileChannel
,
given mapping-mode, given cache-mode and the DEFAULT_SLICE_SHIFT
.
The ByteBuffer
slices will be mapped lazily at first usage.
fileChannel
- the file channel to be used.mmode
- the map mode, default is FileChannel.MapMode#READ_ONLY
.cmode
- the caching mode, default is MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD
.IOException
public MappedByteBufferInputStream(FileChannel fileChannel) throws IOException
FileChannel
,
read-only
mapping mode, MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD
and the DEFAULT_SLICE_SHIFT
.
The ByteBuffer
slices will be mapped FileChannel.MapMode#READ_ONLY
lazily at first usage.
fileChannel
- the file channel to be used.IOException
public final void setSynchronous(boolean s)
If synchronous mode is enabled, mapped buffers will be flushed
if resized
, written to or closing
in read-write
mapping mode.
If synchronous mode is enabled, FileChannel.force(boolean)
is issued
if resizing
or closing
and not in read-only
mapping mode.
s
- true
to enable synchronous modepublic final boolean getSynchronous()
synchronous mode
.public final void close() throws IOException
close
in interface Closeable
close
in interface AutoCloseable
close
in class InputStream
IOException
public final void setFileResizeOp(MappedByteBufferInputStream.FileResizeOp fileResizeOp) throws IllegalStateException
fileResizeOp
- the new MappedByteBufferInputStream.FileResizeOp
.IllegalStateException
- if attempting to set the MappedByteBufferInputStream.FileResizeOp
to a different value than beforepublic final void setLength(long newTotalSize) throws IOException
FileChannel
's size and adjusting this instance
via accordingly
.
User must have a MappedByteBufferInputStream.FileResizeOp
registered
before.
Implementation calls notifyLengthChange(long)
after MappedByteBufferInputStream.FileResizeOp.setLength(long)
.
newTotalSize
- the new total sizeIOException
- if no MappedByteBufferInputStream.FileResizeOp
has been registered
or if a buffer slice operation failedpublic final void notifyLengthChange(long newTotalSize) throws IOException
FileChannel
's size has been changed
and adjusting this instances buffer slices and states accordingly.
Should be called by user API when aware of such event.
newTotalSize
- the new total sizeIOException
- if a buffer slice operation failedpublic final void flush(boolean metaData) throws IOException
OutputStream.flush()
, synchronizes all mapped buffers
from local storage via MappedByteBuffer.force()
as well as the FileChannel.force(boolean)
w/o metaData
.metaData
- TODOIOException
- if this stream has been closed
.public final MappedByteBufferOutputStream getOutputStream(MappedByteBufferInputStream.FileResizeOp fileResizeOp) throws IllegalStateException, IOException
IllegalStateException
- if attempting to set the MappedByteBufferInputStream.FileResizeOp
to a different value than beforeIOException
- if this instance was opened w/ FileChannel.MapMode#READ_ONLY
or if this stream has been closed
.public final ByteBuffer currentSlice() throws IOException
ByteBuffer
slice at the current position()
.
Due to the nature of using sliced buffers mapping the whole region,
user has to determine whether the returned buffer covers the desired region
and may fetch the nextSlice()
until satisfied.
It is also possible to repeat this operation after reposition the stream via position(long)
or skip(long)
to a position within the next block, similar to nextSlice()
.
IOException
- if a buffer slice operation failed.public final ByteBuffer nextSlice() throws IOException
ByteBuffer
slice from the current position()
,
implicitly setting position(long)
to the start of the returned next slice,
see currentSlice()
.
If no subsequent slice is available, null
is being returned.
IOException
- if a buffer slice operation failed.public final MappedByteBufferInputStream.CacheMode getCacheMode()
MappedByteBufferInputStream.CacheMode
.
If a desired MappedByteBufferInputStream.CacheMode
is not available, it may fall back to an available one at runtime,
see MappedByteBufferInputStream.CacheMode.FLUSH_PRE_HARD
.
This evaluation only happens if the MappedByteBufferInputStream.CacheMode
!= MappedByteBufferInputStream.CacheMode.FLUSH_NONE
and while attempting to flush an unused buffer slice.
public final long length()
InputStream
0 <= position()
<= length()
public final long remaining() throws IOException
InputStream
,
i.e. length()
- position()
.
0 <= position()
<= length()
In contrast to InputStream
's available()
method,
this method returns the proper return type long
.
IOException
- if a buffer slice operation failed.public final int available() throws IOException
remaining()
for an accurate variant.
available
in class InputStream
IOException
- if a buffer slice operation failed.public final long position() throws IOException
InputStream
.
0 <= position()
<= length()
IOException
- if a buffer slice operation failed.public final MappedByteBufferInputStream position(long newPosition) throws IOException
newPosition
- The new position, which must be non-negative and ≤ length()
.IOException
- if a buffer slice operation failed or stream is closed
.public final boolean markSupported()
markSupported
in class InputStream
public final void mark(int readlimit)
Parameter readLimit
is not used in this implementation,
since the whole file is memory mapped and no read limitation occurs.
mark
in class InputStream
public final void reset() throws IOException
reset
in class InputStream
IOException
- if this stream has not been marked,
a buffer slice operation failed or stream has been closed
.public final long skip(long n) throws IOException
skip
in class InputStream
IOException
- if a buffer slice operation failed or stream is closed
.public final int read() throws IOException
read
in class InputStream
IOException
public final int read(byte[] b, int off, int len) throws IOException
read
in class InputStream
IOException
public final int read(ByteBuffer b, int len) throws IOException
read(byte[], int, int)
with ByteBuffer
instead of byte array.b
- the ByteBuffer
sink, data is written at current Buffer.position()
len
- the number of bytes to readIOException
- if a buffer slice operation failed or stream has been closed
.