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
- 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
- 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:
Let us understand the important classes contained in these groups.
Package | Purpose |
---|---|
java.nio | It is a top-level package for NIO system. The various types of buffers are encapsulated by this NIO system. |
java.nio.charset | It 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.spi | It supports the service provider for the character sets. |
java.nio.channels | It supports the channel which is essentially open for the I/O connections. |
java.nio.channels.spi | It supports the service providers for the channels. |
java.nio.file | It provides the support for the files. |
java.nio.file.spi | It supports the service providers for the file system. |
java.nio.file.attribute | It provides the support for the file attributes. |
1.2 Java Nio vs. Standard I/O
Topic | IO | Nio |
---|---|---|
Reading/Writing | Provides 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 Files | All 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 Blocking | IO 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. |
Copying | It 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/Gather | Not Available | Nio 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 Operations | IO 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
.
Class | Method | Cause |
ByteBuffer | public abstract ByteBuffer put(byte b) | If this buffer’s current position is not smaller than its limit. |
ByteBuffer | public ByteBuffer put(ByteBuffer src) | If there is insufficient space in this buffer for the remaining bytes in the source buffer. |
ByteBuffer | public final ByteBuffer put(byte[] src) | If there is insufficient space in this buffer. |
ByteBuffer | public abstract ByteBuffer putChar(char value) | If there are fewer than two bytes remaining in this buffer. |
ByteBuffer | public abstract ByteBuffer putShort(short value) | If there are fewer than two bytes remaining in this buffer. |
ByteBuffer | public abstract ByteBuffer putInt(int value) | If there are fewer than four bytes remaining in this buffer. |
ByteBuffer | public abstract ByteBuffer putLong(long value) | If there are fewer than eight bytes remaining in this buffer. |
ByteBuffer | public abstract ByteBuffer putFloat(float value) | If there are fewer than four bytes remaining in this buffer. |
ByteBuffer | public abstract ByteBuffer putDouble(double value) | If there are fewer than eight bytes remaining in this buffer. |
CharBuffer | public abstract CharBuffer put(char c) | If this buffer’s current position is not smaller than its limit. |
CharBuffer | public CharBuffer put(CharBuffer src) | If there is insufficient space in this buffer for the remaining chars in the source buffer. |
CharBuffer | public final CharBuffer put(char[] src) | If there is insufficient space in this buffer. |
CharBuffer | public final CharBuffer put(String src) | If there is insufficient space in this buffer. |
CharBuffer | public CharBuffer append(CharSequence csq) | If there is insufficient space in this buffer. |
CharBuffer | public CharBuffer append(char c) | If there is insufficient space in this buffer. |
DoubleBuffer | public abstract DoubleBuffer put(double d) | If this buffer’s current position is not smaller than its limit. |
DoubleBuffer | public DoubleBuffer put(DoubleBuffer src) | If there is insufficient space in this buffer for the remaining doubles in the source buffer. |
DoubleBuffer | public final DoubleBuffer put(double[] src) | If there is insufficient space in this buffer. |
FloatBuffer | public abstract FloatBuffer put(float f) | If this buffer’s current position is not smaller than its limit. |
FloatBuffer | public FloatBuffer put(FloatBuffer src) | If there is insufficient space in this buffer for the remaining floats in the source buffer. |
FloatBuffer | public final FloatBuffer put(float[] src) | If there is insufficient space in this buffer. |
IntBuffer | public abstract IntBuffer put(int i) | If this buffer’s current position is not smaller than its limit. |
ShortBuffer | public 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.
You can download the full source code of this example here: JavaNioBufferOverflow