Java NIO Buffers

Java NIO Buffers

NIO Buffers provide a mechanism to store a set of data elements in a in-memory container. A buffer is a container of finite capacity of a specific data type. It is akin to a Java array.

NIO Buffers Properties

  • Capacity – A buffer’s capacity is defined by the number of elements it contains. A buffer’s capacity is defined when the allocate() method is called with the number of elements you wish to allocate for the buffer.
  • Limit – A buffer’s limit is the index of the first element that should not be read or written. In read mode, the limit specifies how much data is available to get from the buffer. In wirte mode, it is the amount of space available to put data into.
  • Position – As discussed earlier, a buffer is nothing more a suped-up array. Think of position as the current index at which data will be written to or read from. When you start, position is set to 0. In read mode, as data is read into the buffer and position is advanced by 1. In write mode, the position indicates where in the buffer the write operation will go.

NIO Buffer Subclasses

There are many different kinds of buffers. The most common type of Buffer is ByteBuffer. However, there are buffer types for each of the primitive Java types.

Create and Allocate Buffer

There are several ways to create a buffer.

  1. allocate(int capacity) – allocates a buffer with a size of capacity.
  2. allocateDirect(int capacity) – allocates a direct buffer with a size of capacity. In this case, the JVM will attempt to use native I/O operations upon it.
  3. wrap(byte[] array) – Wraps a byte array into a buffer.

Below is an example showing how to create/allocate a ByteBuffer with a capacity of 256 bytes.

ByteBuffer buffer = ByteBuffer.allocate(256);

Here is an example allocating .a ByteBuffer with a capacity of 2048 bytes. ByteBuffer is a special type of Buffer subclass as it allows you to support direct allocation for improved I/O performance.

ByteBuffer buffer = ByteBuffer.allocateDirect(2048);

Writing Data into a Buffer

Writing data into buffers may be done in several ways:

  1. Using the put() method to write into the buffer directly
  2. Write data into a Buffer via the channel’s read() method

In this example, I am writing into the buffer directly using a String and getting all of the bytes. The put() method has been overloaded and has several variations including put(byte b), put(byte[] src), put(byte[] src, int offset, int length), and put(ByteBuffer src).

JavaNIO_PutBuffer

myBuffer.put(QUOTE.getBytes());

In this example, we are using the Channel’s read() method which reads a sequence of bytes into the buffer.

JavaNIO_FileToBuffer

In the graphic above you can easily see data is read from the file system via the Channel and how the channel then writes this data into the buffer when the read() method is called.

int bytesRead = inChannel.read(myBuffer);

Write String to Text File using NIO Channel and Buffer

package com.avaldes.tutorial;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.apache.log4j.Logger;

public class MyBufferWriteExample {
  private static final Logger logger
                    = Logger.getLogger(MyBufferWriteExample.class);
  private static final int BUFFER_SIZE = 1024;
  private static final String FILE_NAME = "c:\\tmp\\output.txt";
  private static final String QUOTE
      = "If your actions inspire others to dream more, learn "
      + "more, do  more and become more, you are a leader.";

  public static void main(String[] args) throws IOException {
    logger.info("Starting MyBufferWriteExample...");
    FileOutputStream fileOS = new FileOutputStream(FILE_NAME);
    FileChannel channel = fileOS.getChannel();

    try {
      ByteBuffer myBuffer = ByteBuffer.allocate(BUFFER_SIZE);
      myBuffer.put(QUOTE.getBytes());
      myBuffer.flip();

      int bytesWritten = channel.write(myBuffer);
      logger.info(
        String.format("%d bytes have been written to disk...",
        bytesWritten));
      logger.info(
        String.format("Current buffer position is %d",
        myBuffer.position()));
    } finally  {
      channel.close();
      fileOS.close();
  }
}

Reading Data from a Buffer

JavaNIO_BufferToFile

In the above illustration you can see how a process writes data to the buffer and how the information is read from the buffer when the channel’s write() method is called.

int bytesWritten = channel.write(myBuffer);

JavaNIO_GetBuffer

Read Data from a Text File using NIO Channel and Buffer

package com.avaldes.tutorial;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.apache.log4j.Logger;

public class MyBufferReadExample {
  private static final Logger logger
            = Logger.getLogger(MyBufferReadExample.class);
  private static final int BUFFER_SIZE = 1024;
  private static final String FILE_NAME = "c:\\tmp\\output.txt";

  public static void main(String[] args) throws IOException {
    logger.info("Starting MyBufferReadExample...");
    FileInputStream fileIS = new FileInputStream(FILE_NAME);
    FileChannel inChannel = fileIS.getChannel();

    ByteBuffer myBuffer = ByteBuffer.allocate(BUFFER_SIZE);
    while (inChannel.read(myBuffer) > 0) {
      myBuffer.flip();

      while (myBuffer.hasRemaining()) {
        System.out.print((char) myBuffer.get());
      }
      myBuffer.clear();
    }

    inChannel.close();
    fileIS.close();
  }
}

Manipulating Buffer Internals

Next we will look at uing some of the methods available in the Buffer interface hence all classes (ByteBuffer, CharBuffer, etc) will inherit these methods.

flip()

Flip is used to flip the buffer from write mode to read mode. In addition, flip sets the limit to the current position, discards mark, and sets position to 0.

mark() and reset()

The mark() method is used to set the buffer’s mark at the current position. At some point in the future, calling reset() will set the position back to the previously marked position.

Warning

If the mark has not set, invoking reset() will cause an exception called InvalidMarkException.

clear()

The clear() method sets the position to 0, sets the limit to the capacity of the buffer and discards the mark that may have been set. It prepares the buffer for write mode.

rewind()

The rewind() method sets the position to 0 and discards the mark. It prepares the buffer for re-reading.

That’s It!

I hope you enjoyed this tutorial. It was certainly a lot of fun putting it together and testing it out. Please continue to share the love and like us so that we can continue bringing you quality tutorials. Happy Coding!!!

java_nio_buffers

Java NIO Related Tutorials

  • Java NIO Tutorial
    In this tutorial series we discuss the new features of Java NIO.
  • Java NIO Buffers
    This post covers NIO Buffers in more detail and provides practical examples of using buffers in real world applications.
  • Java NIO Channels
    This post covers NIO Channels in more detail and provides examples on network connections and Java I/O in relation to files.
  • Java NIO Selectors
    In this tutorial we learn how to use the Selector class from the java.io.channels package library to build High-Performance I/O client-server using NIO.
  • Java NIO File Channel
    In this tutorial we learn how to use the FileChannel class from the java.io.channels package library and provide working examples on all of the main methods.
  • Java NIO Socket Channel
    In this tutorial we learn how to use the SocketChannel and how it is used for reading/writing stream oriented data and using TCP connection based protocol.
  • Java NIO DatagramChannel Tutorial
    In this tutorial we learn how to use the DatagramChannel to allow developers to build high-performant data streaming applications that send and receive datagrams using a protocol called UDP.
  • Java NIO and NIO2 Path Tutorial
    This tutorial will introduce the Path interface and many of its methods. The Path interface was made available as part of the Java SE 7 release in the Java NIO 2 File API.

Please Share Us on Social Media

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *