Search this site

 Home  I/O  Buffering  Character streams  NIO intro  Buffers  Channels  Buffer performance

Search this site:
Threads Database Profiling Regular expressions Random numbers Compression Exceptions C Equivalents in Java

 What do you think of this article? Did it help you? Found a mistake? Feedback and suggestions here

Java NIO: Buffers

If you've worked with binary file formats, for example in the fields of data recovery or file compatibility, you'll be familiar with the idea of processing "blocks" of data from a file or stream, or processing data as groups of bytes that function together as other types of data such as 4-byte words, Unicode strings etc. For example, you might need to read data in from a file that consists of a "4 byte header", followed by a "4-byte offset" to something, followed by a "2-byte length" etc. Or in a database file, you might need to treat the file as fixed-size "pages" where you read in a page of data from a particular offset, modify it in memory, then write it back to the file.

In the standard java.io package, a file or stream is generally presented to the programmer as a series of bytes or byte array(s). The DataInput and DataOutput interfaces can help out, but they still only work on streams, and crucially don't allow byte order to be specified. Operations such as "read a little-endian 4-byte integer from offset 10" are clumsy in this stream-based model.

This is where the NIO Buffer class and its subclasses come in. A commonly used buffer class is ByteBuffer. This and its cousins:

  • allow a byte array (or block of memory/file) to be managed as a buffer, with methods to deal with the current read/write position, maximum position, byte order etc;
  • provide convenience methods such as putInt(), putLong() etc for accessing specific sizes of data and at a particular offset;
  • are optimized by the JVM (at least in Sun's implementation) so that, for example, a Buffer.get() method can literally be translated into a move instruction at the machine-code level;
  • can provide a mapped view of a file so that, for example, calling putShort() with a particular offset can literally write to that offset in the file.

Additionally, a type of buffer called a direct buffer provides access to a fixed area of memory allocated outside the Java heap.

At present, buffer sizes are limited to 2GB (the maximum positive number that can be represented in an int. An updated planned for Java 7 will allow large buffers (with the size and indexes held as a long).

On the next page, we'll start by having a look at the layout of a NIO buffer. This will help us understand the various methods that can be called on a buffer. We'll then look at the various types of buffer offered as part of the java.nio package, and crucially the ByteBuffer, probably the most common and generic NIO buffer class.

comments powered by Disqus

Written by Neil Coffey. Copyright © Javamex UK 2012. All rights reserved.