Java Reference
In-Depth Information
Buffers are an in-memory abstraction. To affect the outside world (e.g., the file or
network), we need to use a Channel , from the package java.nio.channels . Chan‐
nels represent connections to entities that can support read or write operations.
Files and sockets are the usual examples of channels, but we could consider custom
implementations used for low-latency data processing.
Channels are open when they're created, and can subsequently be closed. Once
closed, they cannot be reopened. Channels are usually either readable or writable,
but not both. The key to understanding channels is that:
• Reading from a channel puts bytes into a buffer
• Writing to a channel takes bytes from a buffer
For example, suppose we have a large file that we want to checksum in 16M chunks:
FileInputStream fis = getSomeStream ();
boolean fileOK = true ;
try ( FileChannel fchan = fis . getChannel ()) {
ByteBuffer buffy = ByteBuffer . allocateDirect ( 16 * 1024 * 1024 );
while ( fchan . read ( buffy ) != - 1 || buffy . position () > 0 || fileOK ) {
fileOK = computeChecksum ( buffy );
buffy . compact ();
}
} catch ( IOException e ) {
System . out . println ( "Exception in I/O" );
}
This will use native I/O as far as possible, and will avoid a lot of copying of bytes on
and off the Java heap. If the computeChecksum() method has been well imple‐
mented, then this could be a very performant implementation.
Mapped Byte Bufers
These are a type of direct byte buffer that contain a memory-mapped file (or a
region of one). They are created from a FileChannel object, but note that the File
object corresponding to the MappedByteBuffer must not be used after the memory-
mapped operations, or an exception will be thrown. To mitigate this, we again use
try -with-resources, to scope the objects tightly:
try ( RandomAccessFile raf =
new RandomAccessFile ( new File ( "input.txt" ), "rw" );
FileChannel fc = raf . getChannel ();) {
MappedByteBuffer mbf =
fc . map ( FileChannel . MapMode . READ_WRITE , 0 , fc . size ());
byte [] b = new byte [( int ) fc . size ()];
mbf . get ( b , 0 , b . length );
for ( int i = 0 ; i < fc . size (); i ++) {
b [ i ] = 0 ; // Won't be written back to the file, we're a copy
}
Search WWH ::




Custom Search