nio

Java Nio BufferOverflowException Example

Exceptions are the unwanted or the unexpected events that occur during the execution of programs that disrupt the normal flow of the instructions. In this tutorial, we will learn about the BufferOverflowException which is very common in the Java Nio package. But before moving ahead let’s take a look and understand the basics of the Java Nio package.
 
 
 
 
 
 
 

1. Introduction

Java Nio was developed to allow the Java programmers implement the high-speed input-output operations without using the custom native code. Nio moves the time-taking I/O activities like filling, namely and draining buffers etc back into the operating system, thus allows the great increase in the operational speed.

Java Nio consists of the following core components:

  • Channel & Buffers: In standard, I/O API the character streams and the byte streams are used but in NIO, developers work with the channels and buffers. In this case, the data is always written from a buffer to a channel and read from a channel to a buffer

    Fig. 1: Channel & Buffers
    Fig. 1: Channel & Buffers
  • Selectors: It is an object that can be used for monitoring the multiple channels for events like data arrived, the connection opened etc. Thus, a single thread can monitor the multiple channels for the data

    Fig. 2: A Thread uses a Selector to handle 3 Channel's
    Fig. 2: A Thread uses a Selector to handle 3 Channel’s
  • Non-blocking I/O: Here the application immediately returns the available data and application should have a pooling mechanism to find out when more data is available

Do note, Java NIO has more components and classes but the Channel, Buffer, and Selector are used as the core of the API.

1.1 Java Nio Components

The Java Nio classes are contained in the java.nio package and it is important to understand that the Nio subsystem does not replace the existing stream-based I/O classes available in java.io package. The important Nio classes are grouped under different categories that are shown below:

Fig. 3: Nio Components
Fig. 3: Nio Components

Let us understand the important classes contained in these groups.

PackagePurpose
java.nioIt is a top-level package for NIO system. The various types of buffers are encapsulated by this NIO system.
java.nio.charsetIt encapsulates the character sets and also supports the encoding and the decoding operations that convert the characters to bytes and bytes to characters.
java.nio.charset.spiIt supports the service provider for the character sets.
java.nio.channelsIt supports the channel which is essentially open for the I/O connections.
java.nio.channels.spiIt supports the service providers for the channels.
java.nio.fileIt provides the support for the files.
java.nio.file.spiIt supports the service providers for the file system.
java.nio.file.attributeIt provides the support for the file attributes.

1.2 Java Nio vs. Standard I/O

TopicIONio
Reading/WritingProvides classes to read and write bytes and characters from files and sockets. The reading and writing can be buffered.Provides channels that interface with the files or sockets to manage the data. There is no specific advantage to using Nio over IO.
Large FilesAll files need to be loaded into the JVM, hence handling large files may be difficult.Memory Mapped Buffers allows mapping a file directly from the file system (i.e. without loading them into memory). It would be possible to handle very large files without running out of heap space.
Threads and BlockingIO is blocking in nature. For example, if developers open a socket connection, a dedicated thread is required to handle the socket client.Nio can be implemented in a non-blocking fashion. Using the socket example, a selector framework selects a socket client when it has the data available. The availability notification may be provided by the File System.
CopyingIt is accomplished by reading from a file into the JVM and writing back to another file.Copying can be accomplished by directly transferring the data from one channel to another and therefore copying the large files may be faster.
Scatter/GatherNot AvailableNio provides classes and methods to read from a channel into multiple buffers in a single operation and also write from multiple buffers into a single channel.
File OperationsIO provides the ‘File’ class that represents the actual file.Nio provides the ‘Path’ class that holds the path to the actual file. Path combined with the java.nio.file.Files class provides a lot of powerful functionalities that include walking a directory tree.

2. The BufferOverflow Exception in Java Nio

BufferOverflow Exception is an unchecked/runtime exception thrown when a relative put operation reaches the target buffer’s limit i.e. as the name say, it’s thrown when the buffer reaches the maximum size.

java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
java.nio.BufferOverflowException

2.1 Sample Code

In order to understand the behavior of the java.nio.BufferOverflowException, we have written a sample code to prove that the exception definition holds well. An example that throws a BufferOverflowException is shown below:

Code Snippet #1

// Sample Code To Analyse The BufferOverflow Exception
File sampleFile = new File("config/sample.txt");
try (RandomAccessFile raf = new RandomAccessFile(sampleFile, "rw")) {
	FileChannel fileChannel = raf.getChannel();
	MappedByteBuffer buf = fileChannel.map(MapMode.READ_WRITE, 0, sampleFile.length());

	final byte[] src = new byte[1000];
	System.out.println(src.length > sampleFile.length());
	buf.put(src);
} catch (IOException ioException) {
	ioException.printStackTrace();
}

In this example, the mapped byte buffer returned by the executing method will have a position of zero i.e. if the src.length > sampleFile.length(), the code will throw a BufferOverflowException. So, if and only if, a true value is printed at line no. 8, the exception is thrown.

Exception in thread "main" java.nio.BufferOverflowException
	at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:363)
	at java.nio.ByteBuffer.put(ByteBuffer.java:859)
	at com.jcg.java.nio.BufferOverflowException.main(BufferOverflowException.java:22)

2.2 Possible Causes of BufferOverflowException

The below table lists down the possible causes for the BufferOverflowException.

ClassMethodCause
ByteBufferpublic abstract ByteBuffer put(byte b)If this buffer’s current position is not smaller than its limit.
ByteBufferpublic ByteBuffer put(ByteBuffer src)If there is insufficient space in this buffer for the remaining bytes in the source buffer.
ByteBufferpublic final ByteBuffer put(byte[] src)If there is insufficient space in this buffer.
ByteBufferpublic abstract ByteBuffer putChar(char value)If there are fewer than two bytes remaining in this buffer.
ByteBufferpublic abstract ByteBuffer putShort(short value)If there are fewer than two bytes remaining in this buffer.
ByteBufferpublic abstract ByteBuffer putInt(int value)If there are fewer than four bytes remaining in this buffer.
ByteBufferpublic abstract ByteBuffer putLong(long value)If there are fewer than eight bytes remaining in this buffer.
ByteBufferpublic abstract ByteBuffer putFloat(float value)If there are fewer than four bytes remaining in this buffer.
ByteBufferpublic abstract ByteBuffer putDouble(double value)If there are fewer than eight bytes remaining in this buffer.
CharBufferpublic abstract CharBuffer put(char c)If this buffer’s current position is not smaller than its limit.
CharBufferpublic CharBuffer put(CharBuffer src)If there is insufficient space in this buffer for the remaining chars in the source buffer.
CharBufferpublic final CharBuffer put(char[] src)If there is insufficient space in this buffer.
CharBufferpublic final CharBuffer put(String src)If there is insufficient space in this buffer.
CharBufferpublic CharBuffer append(CharSequence csq)If there is insufficient space in this buffer.
CharBufferpublic CharBuffer append(char c)If there is insufficient space in this buffer.
DoubleBufferpublic abstract DoubleBuffer put(double d)If this buffer’s current position is not smaller than its limit.
DoubleBufferpublic DoubleBuffer put(DoubleBuffer src)If there is insufficient space in this buffer for the remaining doubles in the source buffer.
DoubleBufferpublic final DoubleBuffer put(double[] src)If there is insufficient space in this buffer.
FloatBufferpublic abstract FloatBuffer put(float f)If this buffer’s current position is not smaller than its limit.
FloatBufferpublic FloatBuffer put(FloatBuffer src)If there is insufficient space in this buffer for the remaining floats in the source buffer.
FloatBufferpublic final FloatBuffer put(float[] src)If there is insufficient space in this buffer.
IntBufferpublic abstract IntBuffer put(int i)If this buffer’s current position is not smaller than its limit.
ShortBufferpublic final ShortBuffer put(short[] src)If there is insufficient space in this buffer.

2.3 Handing BufferOverflowException

The code snippet shown below illustrates the use of ByteBuffer to create a string. This approach helps developers avoid the BufferOverflowException in the application. Developers can debug this example and see what happens after every step!

Code Snippet #2

// Allocate A New Non-Direct Bytebuffer With A 100 Byte Capacity & Set This To A Big Value Avoid The 'BufferOverflowException'.
ByteBuffer buf = ByteBuffer.allocate(100);

// Creates A View Of This Byte Buffer As A Char Buffer.
CharBuffer cbuf = buf.asCharBuffer();

// Write A String To Char Buffer.
cbuf.put("Hello Java Code Geek!");

// Flips This Buffer. The Limit Is Set To The Current Position And Then The Position Is Set To Zero. If The Mark Is Defined Then It Is Discarded.
cbuf.flip();

String str = cbuf.toString();
System.out.println(str);

NOTE: What if developers flip a buffer twice? It effectively becomes zero-sized i.e. both the buffer attributes, limit and position will become zero. Now attempting a put() operation on the buffer causes a BufferOverflowException.

That’s all for this post. Happy Learning!!

3. Conclusion

This tutorial uses a simple example to illustrate the BufferOverflowException and helps developers understand the configuration required to avoid this exception. That’s all for this tutorial and I hope this article served you whatever you were looking for.

4. Download the Eclipse Project

This was an example of Java Nio for the beginners.

Download
You can download the full source code of this example here: JavaNioBufferOverflow

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
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