Package org.apache.commons.io.input
Class BufferedFileChannelInputStream
java.lang.Object
java.io.InputStream
org.apache.commons.io.input.BufferedFileChannelInputStream
- All Implemented Interfaces:
Closeable
,AutoCloseable
InputStream
implementation which uses direct buffer to read a file to avoid extra copy of data between Java
and native memory which happens when using BufferedInputStream
. Unfortunately, this is not something
already available in JDK, sun.nio.ch.ChannelInputStream
supports reading a file using NIO, but does not
support buffering.
This class was ported and adapted from Apache Spark commit 933dc6cb7b3de1d8ccaf73d124d6eb95b947ed19 where it was
called NioBufferedFileInputStream
.
- Since:
- 2.9.0
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final ByteBuffer
private static final Class<?>
private final FileChannel
-
Constructor Summary
ConstructorsConstructorDescriptionConstructs a new instance for the given File.BufferedFileChannelInputStream
(File file, int bufferSizeInBytes) Constructs a new instance for the given File and buffer size.Constructs a new instance for the given Path.BufferedFileChannelInputStream
(Path path, int bufferSizeInBytes) Constructs a new instance for the given Path and buffer size. -
Method Summary
Modifier and TypeMethodDescriptionint
private void
clean
(ByteBuffer buffer) Attempts to clean up a ByteBuffer if it is direct or memory-mapped.private void
cleanDirectBuffer
(ByteBuffer buffer) In Java 8, the type of DirectBuffer.cleaner() was sun.misc.Cleaner, and it was possible to access the method sun.misc.Cleaner.clean() to invoke it.void
close()
private static Class<?>
private static boolean
isDirectBuffer
(Object object) int
read()
int
read
(byte[] b, int offset, int len) private boolean
refill()
Checks whether data is left to be read from the input stream.long
skip
(long n) private long
skipFromFileChannel
(long n) Methods inherited from class java.io.InputStream
mark, markSupported, nullInputStream, read, readAllBytes, readNBytes, readNBytes, reset, skipNBytes, transferTo
-
Field Details
-
byteBuffer
-
fileChannel
-
DIRECT_BUFFER_CLASS
-
-
Constructor Details
-
BufferedFileChannelInputStream
Constructs a new instance for the given File.- Parameters:
file
- The file to stream.- Throws:
IOException
- If an I/O error occurs
-
BufferedFileChannelInputStream
Constructs a new instance for the given File and buffer size.- Parameters:
file
- The file to stream.bufferSizeInBytes
- buffer size.- Throws:
IOException
- If an I/O error occurs
-
BufferedFileChannelInputStream
Constructs a new instance for the given Path.- Parameters:
path
- The path to stream.- Throws:
IOException
- If an I/O error occurs
-
BufferedFileChannelInputStream
Constructs a new instance for the given Path and buffer size.- Parameters:
path
- The path to stream.bufferSizeInBytes
- buffer size.- Throws:
IOException
- If an I/O error occurs
-
-
Method Details
-
getDirectBufferClass
-
isDirectBuffer
-
available
- Overrides:
available
in classInputStream
- Throws:
IOException
-
clean
Attempts to clean up a ByteBuffer if it is direct or memory-mapped. This uses an *unsafe* Sun API that will cause errors if one attempts to read from the disposed buffer. However, neither the bytes allocated to direct buffers nor file descriptors opened for memory-mapped buffers put pressure on the garbage collector. Waiting for garbage collection may lead to the depletion of off-heap memory or huge numbers of open files. There's unfortunately no standard API to manually dispose of these kinds of buffers.- Parameters:
buffer
- the buffer to clean.
-
cleanDirectBuffer
In Java 8, the type of DirectBuffer.cleaner() was sun.misc.Cleaner, and it was possible to access the method sun.misc.Cleaner.clean() to invoke it. The type changed to jdk.internal.ref.Cleaner in later JDKs, and the .clean() method is not accessible even with reflection. However sun.misc.Unsafe added a invokeCleaner() method in JDK 9+ and this is still accessible with reflection.- Parameters:
buffer
- the buffer to clean. must be a DirectBuffer.
-
close
- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
- Overrides:
close
in classInputStream
- Throws:
IOException
-
read
- Specified by:
read
in classInputStream
- Throws:
IOException
-
read
- Overrides:
read
in classInputStream
- Throws:
IOException
-
refill
Checks whether data is left to be read from the input stream.- Returns:
- true if data is left, false otherwise
- Throws:
IOException
-
skip
- Overrides:
skip
in classInputStream
- Throws:
IOException
-
skipFromFileChannel
- Throws:
IOException
-