Buffer

java.nio.Buffer Example

This article introduces the Buffer class and its basic usage. This class is defined in the java.nio package.

A buffer is a container for a fixed amount of data of a specific primitive type. There is one subclass of this class for each primitive type, except boolean. They are ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer and ShortBuffer classes. These are also defined in the java.nio package.

The example programs use byte buffer and char buffer classes as buffers are created and used as one of the subclasses. The examples are compiled and run in Windows OS environment. Note that Java SE 7 is required to run the code.

Essential properties

  • Capacity: This is the number of elements it contains.
  • Position: This is the index of the next element to be read or written.
  • Limit: This is the index of the first element that should not be read or written.

There are methods to examine these properties: capacity(), position() and limit().

Creating a buffer

A buffer can be created by invoking one of the static methods of its subclasses.

The allocate() method creates a buffer with its specified initial capacity. The wrap() method wraps an existing byte array into it and creates a buffer.

Transferring data

There are get() and put() methods of the subclasses for moving data out of and in to a buffer. Data may also be transferred in to or out of a buffer by the I/O operations of an appropriate channel. Channel classes are defined in java.nio.channels package.

Buffer operations

Buffer class defines methods for clearing, flipping, and rewinding, for marking the current position, and for resetting the position to the previous mark.

Read only buffer

The buffer subclasses can be created as read only buffers by invoking the class’s asReadOnlyBuffer() method.

Direct buffers

A buffer can be allocated as a direct buffer.

For a direct buffer, the Java virtual machine will make a best effort to perform native I/O operations directly upon it. That is, it will attempt to avoid copying the buffer’s content to (or from) an intermediate buffer before (or after) each invocation of one of the underlying operating system’s native I/O operations.

A direct buffer may be created by invoking the allocateDirect() factory method of a buffer subclass.

Also, see an example of Java Direct ByteBuffer.

Thread safety

Buffers are not safe for use by multiple concurrent threads. If a buffer is to be used by more than one thread, then access to the buffer should be controlled by appropriate synchronization.

1. Example 1

This example shows buffer’s basic operations: creating, writing to and reading from a buffer, and verifying its contents. The example uses a CharBuffer.

1.1. Create buffer

CharBuffer buffer = CharBuffer.allocate(8);

The above code snippet creates a char buffer of 8 character initial capacity. The capacity() method, if invoked, returns the value 8.

The new buffer’s position will be zero, its limit will be its capacity, its mark will be undefined, and each of its elements will be initialized to zero. It will have a backing array, and its array offset will be zero.

1.2. Write to the buffer

A text string is written to the buffer, one character at a time.

String text = "apple";

for (int i = 0; i < text.length(); i++) {

	char c = text.charAt(i);
	buffer.put(c);
}

The put() method of the char buffer is invoked to write a character input to the buffer. This writes at the current position and then increments the position.

NOTE: There is also a bulk put() method which takes a character array (char []) as input parameter, and writes the array contents to the buffer.

1.3. Verify the position

int buffPos = buffer.position();

The value will be 5, after the put operation.

1.4. Read buffer contents

buffer.flip();

Buffer’s flip() method sets the limit to the current position (i.e., 5) and the position is set to zero. This operation is required to read the buffer from the initial position.

Read the buffer contents, one character at a time, by invoking char buffer’s get() method.

while (buffer.hasRemaining()) {

	System.out.println(buffer.get());                   
}

NOTE: There is also a bulk get() method which takes a character array (char []) as input parameter, and reads the buffer contents into to the array.

The following is the example program’s complete code and its output.

1.5. The code

BufferExample1.java

import java.nio.CharBuffer;

public class BufferExample1 {

    public static void main (String [] args) {
	
        CharBuffer buffer = CharBuffer.allocate(8);

        String text = "apple";
        System.out.println("Input text: " + text);

        for (int i = 0; i < text.length(); i++) {

            char c = text.charAt(i);
            buffer.put(c);
        }

        int buffPos = buffer.position();
        System.out.println("Position after data is written into buffer: " + buffPos);

        buffer.flip();
		
        System.out.println("Reading buffer contents:");
		
        while (buffer.hasRemaining()) {

            System.out.println(buffer.get());                   
        }
    }
}

1.6. The output

Input text: apple
Position after data is written into buffer: 5
Reading buffer contents:
a
p
p
l
e

2. Example 2

This example shows usage of ByteBuffer with a FileChannel.

Byte buffers are distinguished from other buffers in that they can be used as the sources and targets of I/O operations. A file channel is a channel for reading, writing and manipulating a file. This channel reads a file into a given byte buffer and writes to a file from a buffer.

The following is the example program’s complete code and its output.

2.1. The code

BufferExample2.java

import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.io.IOException;

public class BufferExample2 {

    public static void main (String [] args) 
            throws IOException {
	
        String testFile = "testfile.txt";
        Path filePath = Paths.get(testFile);
	
        writeFile(filePath);

        readFile(filePath);
    }
	
    private static void writeFile(Path filePath)
            throws IOException {
			
        String input = "Let us go and eat!";
        System.out.println("Text written to file [" + filePath.getFileName() + "]: " + input);
		
        byte [] inputBytes = input.getBytes();
        ByteBuffer writeBuffer = ByteBuffer.wrap(inputBytes);
		
        FileChannel writeChannel = FileChannel.open(filePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
		
        int noOfBytesWritten = writeChannel.write(writeBuffer);
		
        writeChannel.close();
    }
	
    private static void readFile(Path filePath)
            throws IOException {
		
        FileChannel readChannel = FileChannel.open(filePath);
		
        ByteBuffer readBuffer = ByteBuffer.allocate(24);
        int noOfBytesRead = readChannel.read(readBuffer);
		
        byte [] bytes = readBuffer.array();
        String output = new String(bytes).trim();
		
        System.out.println("Text read from file [" + filePath.getFileName() + "]: " + output);
		
        readChannel.close();
    }
}

From the above code:

  • In the writeFile() method on line 28, the buffer is constructed by invoking the ByteBuffer‘s wrap() static method. This method takes a byte array (byte []) as input parameter. The array contents are loaded into the buffer. NOTE: This byte array is a backing array. Note that any modifications to this buffer’s content will cause the backing array’s content to be modified, and vice-versa.
  • In the readFile() method on line 45, the byte buffer’s array() method returns the backing byte array with the contents of the buffer.

NOTE: Also, see example of file channel using byte buffer at java.nio.channels.FileChannel Example.

2.2. The output

Text written to file [testfile.txt]: Let us go and eat!
Text read from file [testfile.txt]: Let us go and eat!

3. Download Java Source Code

This was an example of java.nio.Buffer.

Download
You can download the full source code of this example here: BufferExamples.zip

Prasad Saya

Prasad Saya is a software engineer with over ten years’ experience in application development, maintenance, testing and consulting on various platforms. He is a certified Java and Java EE developer. At present his interest is in developing Java applications. He also has experience working with databases and ERP applications.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button