Java NIO Buffers are used when interacting with NIO channels, as we know from our use of channels. As you know, data is read into the buffer from a channel and written to the channel from the buffer. A buffer is essentially a block of memory into which you can write data, which you can then read again. This memory block is encapsulated in a NIO Buffer object, which provides a set of methods that make it easier to use the memory block. Reading and writing data using a Buffer usually follows the following four steps:

  1. Write data into the Buffer
  2. Call buffer.flip()
  3. Read data out of the Buffer
  4. Call Buffer.clear () or buffer.compact() When you write data to the buffer, the buffer records the amount of data you write. Once you need to read data, you need to switch the buffer from write mode to read mode using the flip () method call. In read mode, the buffer lets you read all the data written to the buffer.

Once you have read all the data, you need to clear the buffer and make it ready to write again. You can do this in two ways: by calling clear () or compact (). The clear () method clears the entire buffer. The compact () method only clears data that has already been read. Any unread data is moved to the beginning of the buffer, and the data is written to the buffer after the unread data.

Here is a simple example of using Buffer:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt"."rw");
FileChannel inChannel = aFile.getChannel();

//create buffer with capacity of 48 bytes
ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buf); // Read from bufferwhile(bytesRead ! = -1) { buf.flip(); // Eject data from bufferwhile(buf.hasRemaining()){ System.out.print((char) buf.get()); } buf.clear(); //make buffer readyfor writing
  bytesRead = inChannel.read(buf);
}
aFile.close();
Copy the code

The three properties of the Buffer

  • capacity
  • position
  • Limit The meaning of limit and position depends on whether the buffer is in read or write mode. Capacity always means the same regardless of buffer mode.

Capacity, position, and limit in write and read mode are described below. The explanation is shown in the figure below.

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • Shortbuffers As you can see, these Buffer types represent different data types. In other words, they let you use char, short, int, long, float, or double to handle bytes in the buffer. To get a Buffer object, you must first allocate it. Each Buffer class has an allocate () method. Here is an example of a 48-byte ByteBuffer allocation:
ByteBuffer buf = ByteBuffer.allocate(48);
Copy the code

This is an example of allocating a CharBuffer of 1024 characters

CharBuffer buf = CharBuffer.allocate(1024);
Copy the code

You can write data to the Buffer in two ways:

  1. Writes data from a channel to a buffer
  2. Write data to the buffer itself via the buffer’s put () method. Here is an example that shows how a channel writes data to a buffer:
int bytesRead = inChannel.read(buf); 
Copy the code

Here is an example of writing data to a Buffer using the put () method:

buf.put(127);    
Copy the code

There are many other versions of the put () method that allow you to write data to buffers in many different ways. For example, write to a specific location, or write to a buffer array of bytes. See JavaDoc for concrete buffer implementation for more details. The flip() method switches Buffer from write mode to read mode. Calling flip () sets the position back to 0 and sets the limit at the position just above. In other words, the position is now marked as the read position, and limits how many bytes, characters, etc., the mark can be written to the buffer.

  1. Reads data from a buffer to a channel.
  2. Use one of the get () methods to read the data from the buffer yourself. Here is an example of how to read data from a buffer into a channel:
int bytesWritten = inChannel.write(buf);
Copy the code

Here is an example of reading data from a Buffer using the get () method:

byte aByte = buf.get();    
Copy the code

There are many other versions of the get () method that allow you to read data from Buffer in a variety of ways. For example, reading a specific location, or reading a byte array from a buffer. See JavaDoc for concrete buffer implementation for more details. The ###rewind() method buffer.rewind () sets the position back to 0, so you can re-read all the data in the Buffer. This limit remains the same, so it still marks how many elements (bytes, characters, etc.) can be read from the buffer. ###clear() and compact()

  1. Once you have finished reading data from the buffer, you must make the buffer ready to write again. You can do this by calling clear () or by calling Compact ().
  2. If you call clear (), the position is set back to 0 and limited to capacity. In other words, the buffer is cleared. The data in the buffer is not cleared. Only tags tell you where you can write to the Buffer.
  3. But if there is any unread data in Buffer when clear () is called, the data is “forgotten,” which means you no longer have any markers to indicate what has been read and what hasn’t been read.
  4. If there is still unread data in the buffer and you want to read it later, but you need to write some data first, call Compact () instead of clear ().
  5. Compact () copies all unread data to the beginning of the Buffer. It then sets the position after the last unread element. The limit property is still set to capacity, just like clear (). The buffer is now ready to write, but will not overwrite unread data. You can mark a given position in the Buffer by calling the buffer.mark () method. You can then reset the position back to the marked position by calling the buffer.reset () method. Here’s an example:
buffer.mark();

//call buffer.get() a couple of times, e.g. during parsing.

buffer.reset();  //set position back to mark.  
Copy the code

You can compare two buffers using equals() and compareTo(). #####equals()

  1. They are of the same type (byte, char, int, etc.)
  2. They have the same number of remaining bytes, characters, etc. in the buffer.
  3. All remaining bytes, characters, etc. are equal. As you can see, equals only compares a portion of the buffer, not each element. In fact, it just compares the rest of the elements in the buffer. #####compareTo() The compareTo() method compares the remaining elements (bytes, characters, etc.) of two buffers, used for example for sorting. A buffer is considered “smaller” than another buffer if:
  4. The first element is equal to the corresponding element in the other buffer and less than the element in the other buffer.
  5. All elements are equal, but the first buffer runs out of elements before the second buffer (there are fewer elements).