Class FileHandle
- All Implemented Interfaces:
Closeable
,AutoCloseable
,ByteChannel
,Channel
,ReadableByteChannel
,SeekableByteChannel
,WritableByteChannel
A representation of an open file. Designed to ensure predictable cleanup for open file descriptors.
This class is basically just a wrapper around a FileChannel
that only exposes some of its methods. It serves
two purposes:
- It creates an extra layer of indirection between the FileChannel and application code, to allow for reachability-sensitive cleanup.
- It's a convenient place to add instrumentation and/or modified implementations when necessary.
The current implementation adds a post-close procedure for integration with caches/trackers, and stats for all operations.
Note that positional methods, e.g. position()
, position(long)
, read(ByteBuffer)
, and
write(ByteBuffer)
may require external synchronization if used concurrently by more than one thread.
-
Constructor Summary
ConstructorsConstructorDescriptionFileHandle
(@NotNull FileChannel fileChannel, @NotNull Runnable postCloseProcedure) Deprecated. -
Method Summary
Modifier and TypeMethodDescriptionfinal void
close()
Close this file handle and release underlying resources.boolean
equalsFileKey
(@NotNull FileHandle other) Checks if two file handles are equal based on theirBasicFileAttributes.fileKey()
on a best-effort basis.final void
force()
Force updates (including metadata) to the underlying file to be written to *local* storage.final boolean
isOpen()
Tells whether this file handle is open.static FileHandle
open
(@NotNull Path path, @NotNull Supplier<Runnable> postCloseProcedureSupplier, @NotNull OpenOption... options) Creates a new file handle by wrapping up the results of anFileChannel.open(Path, OpenOption...)
.final long
position()
Get this file handle's position.final FileHandle
position
(long newPosition) Advance the position of this file handle to the specified new position.final int
read
(@NotNull ByteBuffer destination) Attempt to readdestination.remaining()
bytes, beginning at the handle's current position and updating that position by the number of bytes read.final int
read
(@NotNull ByteBuffer destination, long position) Attempt to readdestination.remaining()
bytes, starting fromposition
(0-indexed) in the file.final long
size()
Get the current size of the file.final FileHandle
truncate
(long size) Truncate this file to the supplied size.final int
write
(@NotNull ByteBuffer source) Attempt to writesource.remaining()
bytes to this file handle, beginning at the handle's current position (which is first advanced to the end of the file, if the underlyingFileChannel
was opened withStandardOpenOption.APPEND
), and updating that position by the number of bytes written.final int
write
(@NotNull ByteBuffer source, long position) Attempt to writesource.remaining()
bytes, starting fromposition
(0-indexed) in the file.
-
Constructor Details
-
FileHandle
@Deprecated public FileHandle(@NotNull @NotNull FileChannel fileChannel, @NotNull @NotNull Runnable postCloseProcedure) Deprecated.Wrap the supplied
FileChannel
.If the
postCloseProcedure
throws an exception, that exception may suppressClosedChannelException
s that triggerpostCloseProcedure
invocation.- Parameters:
fileChannel
- TheFileChannel
postCloseProcedure
- A procedure to invoke if its detected that theFileChannel
is closed - must be idempotent
-
-
Method Details
-
open
public static FileHandle open(@NotNull @NotNull Path path, @NotNull @NotNull Supplier<Runnable> postCloseProcedureSupplier, @NotNull @NotNull OpenOption... options) throws IOException Creates a new file handle by wrapping up the results of anFileChannel.open(Path, OpenOption...)
.If the
Runnable
created frompostCloseProcedureSupplier
throws an exception, that exception may suppressClosedChannelException
s that triggerpostCloseProcedure
invocation.By default, the returned file handle will contain its
file key
to act as a safety check during refreshes of the file handle as part ofFileHandleAccessor
. To disable this safety check, the configuration property "FileHandle.safetyCheckEnabled" can be set tofalse
.- Parameters:
path
- The path to the filepostCloseProcedureSupplier
- A supplier for a procedure to invoke if it's detected that theFileChannel
is closed - the procedure must be idempotent. The supplier will be called exactly once after theFileChannel
has been successfully created.options
- the open options- Returns:
- the file handle
- Throws:
IOException
- if an IO exception occurs
-
equalsFileKey
Checks if two file handles are equal based on theirBasicFileAttributes.fileKey()
on a best-effort basis. This method should only returnfalse
when it is known that the file handles refer to different files - that is, the bias is for this method to returntrue
. The exact semantics of "file key equivalence" is filesystem-dependant, but the general expectation is that UNIX filesystems will use device ID and inode to accomplish this. (A UNIX filesystem may choose to re-use device ID and inode after a file has been deleted. In this case, it is possible for two file handles that referenced two separate files to have "file key equivalence", and is one of the reason why this method must be biased in thetrue
direction.)If the configuration property "FileHandle.safetyCheckEnabled" is
false
, this method will always returntrue
.- Parameters:
other
- the other file handle- Returns:
- true if the file keys are equal
-
size
Get the current size of the file.
See
FileChannel.size()
.- Specified by:
size
in interfaceSeekableByteChannel
- Returns:
- The current size of the file
- Throws:
IOException
-
position
Get this file handle's position.
- Specified by:
position
in interfaceSeekableByteChannel
- Returns:
- This file handle's position
- Throws:
IOException
-
position
Advance the position of this file handle to the specified new position.
- Specified by:
position
in interfaceSeekableByteChannel
- Parameters:
newPosition
- The new position- Returns:
- This file handle
- Throws:
IOException
-
read
Attempt to read
destination.remaining()
bytes, starting fromposition
(0-indexed) in the file.- Parameters:
destination
- The destination to read toposition
- The position in the file to start reading from- Returns:
- The number of bytes read, or -1 if end of file is reached
- Throws:
IOException
-
read
Attempt to read
destination.remaining()
bytes, beginning at the handle's current position and updating that position by the number of bytes read.- Specified by:
read
in interfaceReadableByteChannel
- Specified by:
read
in interfaceSeekableByteChannel
- Parameters:
destination
- The destination to read to- Returns:
- The number of bytes read, or -1 of end of file is reached
- Throws:
IOException
-
write
Attempt to write
source.remaining()
bytes, starting fromposition
(0-indexed) in the file.- Parameters:
source
- The source to write fromposition
- The position in the file to start writing at- Returns:
- The number of bytes written
- Throws:
IOException
-
write
Attempt to write
source.remaining()
bytes to this file handle, beginning at the handle's current position (which is first advanced to the end of the file, if the underlyingFileChannel
was opened withStandardOpenOption.APPEND
), and updating that position by the number of bytes written.- Specified by:
write
in interfaceSeekableByteChannel
- Specified by:
write
in interfaceWritableByteChannel
- Parameters:
source
- The source to write from- Returns:
- The number of bytes written
- Throws:
IOException
-
truncate
Truncate this file to the supplied size.
- Specified by:
truncate
in interfaceSeekableByteChannel
- Parameters:
size
- The new size- Returns:
- This handle
- Throws:
IOException
-
force
Force updates (including metadata) to the underlying file to be written to *local* storage.
- Throws:
IOException
-
isOpen
public final boolean isOpen()Tells whether this file handle is open.
-
close
Close this file handle and release underlying resources.
- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceChannel
- Specified by:
close
in interfaceCloseable
- Throws:
IOException
-
open(Path, Supplier, OpenOption...)