Java Reference
In-Depth Information
FileChannel channel =
(FileChannel)(Files.newByteChannel(file, EnumSet.of(READ,
WRITE)));
This stores the reference that the
newByteChannel()
method as type
FileChannel
because you want
to call the
map()
method that the
FileChannel
class defines. Opening the channel for both reading and
writing is essential here because you want to access and change the contents of the
MappedByteBuffer
object. Notice that the program uses a regular
try
block instead of a
try
block with resources. This is
because you want to close the channel as soon as the memory mapping is established so as to demon-
strate that it works independently from the channel.
You create and load a
MappedByteBuffer
object with the statement:
MappedByteBuffer buf =
channel.map(READ_WRITE, 0L,
channel.size()).load();
The buffer is created with the
READ_WRITE
mode specified, which permits the buffer to be accessed
and modified. The buffer maps to the entire file because you specify the start file position as zero,
and the length that is mapped is the length of the file. The
map()
method returns a reference to the
MappedByteBuffer
object that is created, and you use this to call its
load()
method to request that the
contents of the file be loaded into memory immediately. The
load()
method also returns the same buffer
reference, and you store that in
buf
.
Note that you are not obliged to call the
load()
method before you access the data in the buffer. If the
data is not available when you try to access it through the
MappedByteBuffer
object, it is loaded for you.
Try running the example with the call to
load()
removed. It should work the same as before.
The next statement closes the file channel because it is no longer required:
channel.close(); // Close the channel
It is not essential to close the channel, but doing so demonstrates that memory-mapped file operations
are independent of the channel after the mapping has been established.
Inside the
for
loop, you retrieve a value from the buffer at a random position,
index
:
primes[i] = buf.getLong(index);
You have no need to execute any explicit
read()
operations. The file contents are available directly
through the buffer and any read operations that need to be executed to make the data you are accessing
available are initiated automatically.
Next, you change the value at the position from which you retrieved the value that you store in
primes[i]
:
buf.putLong(index, REPLACEMENT);
This statement changes the contents of the buffer, and this change is subsequently written to the file at
some point. When this occurs depends on the underlying operating system.'
Finally, you output the contents of the
primes
array. You have been able to access and modify the con-
tents of the file without having to execute any explicit I/O operations on the file. For large files where