一、BufferOverflowException 概述
- BufferOverflowException 是 Java NIO 包中的一个运行时异常,是 RuntimeException 的子类
public class BufferOverflowException extends RuntimeException {
...
}
# 继承关系
java.lang.Object
-> java.lang.Throwable
-> java.lang.Exception
-> java.lang.RuntimeException
-> java.nio.BufferOverflowException
- 它发生在尝试向缓冲区写入比可用空间更多的数据时,即缓冲区位置(position)已经到达或超过限制(limit)
二、常见发生场景
- 写入数据
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
int i1 = 10;
byteBuffer.putInt(i1);
System.out.println("第 1 次添加数据:" + i1);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
int i2 = 20;
byteBuffer.putInt(i2);
System.out.println("第 2 次添加数据:" + i2);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
int i3 = 30;
byteBuffer.putInt(i3);
System.out.println("第 3 次添加数据:" + i3);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
# 输出结果
初始化
pos=0, remaining=10, limit=10
第 1 次添加数据:10
pos=4, remaining=6, limit=10
第 2 次添加数据:20
pos=8, remaining=2, limit=10
Exception in thread "main" java.nio.BufferOverflowException
- 批量写入数据
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
String data1 = "Hello1";
byteBuffer.put(data1.getBytes());
System.out.println("第 1 次添加数据:" + data1);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
String data2 = "Hello2";
byteBuffer.put(data2.getBytes());
System.out.println("第 2 次添加数据:" + data2);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
# 输出结果
初始化
pos=0, remaining=10, limit=10
第 1 次添加数据:Hello1
pos=6, remaining=4, limit=10
Exception in thread "main" java.nio.BufferOverflowException
三、避免策略
1、基本介绍
- 总是调用 remaining 方法检查剩余空间是否足够,不同的写入方法对写入长度有不同的要求
方法 | 读取长度(字节) |
---|
ByteBuffer put(byte b) | 1 |
ByteBuffer putChar(char value) | 2 |
ByteBuffer putShort(short value) | 2 |
ByteBuffer putInt(int value) | 4 |
ByteBuffer putLong(long value) | 8 |
ByteBuffer putFloat(float value) | 4 |
ByteBuffer putDouble(double value) | 8 |
ByteBuffer put(byte[] src) | src.length |
- 必要时,也可以通过 try catch 捕获异常
2、演示
- 写入数据(调用 remaining 方法检查)
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
if (byteBuffer.remaining() >= 4) {
int i1 = 10;
byteBuffer.putInt(i1);
System.out.println("第 1 次添加数据:" + i1);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
} else {
System.out.println("第 1 次添加数据");
System.out.println("剩余空间不足,无法添加数据");
}
if (byteBuffer.remaining() >= 4) {
int i2 = 20;
byteBuffer.putInt(i2);
System.out.println("第 2 次添加数据:" + i2);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
} else {
System.out.println("第 2 次添加数据");
System.out.println("剩余空间不足,无法添加数据");
}
if (byteBuffer.remaining() >= 4) {
int i3 = 30;
byteBuffer.putInt(i3);
System.out.println("第 3 次添加数据:" + i3);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
} else {
System.out.println("第 3 次添加数据");
System.out.println("剩余空间不足,无法添加数据");
}
# 输出结果
初始化
pos=0, remaining=10, limit=10
第 1 次添加数据:10
pos=4, remaining=6, limit=10
第 2 次添加数据:20
pos=8, remaining=2, limit=10
第 3 次添加数据
剩余空间不足,无法添加数据
- 批量写入数据(调用 remaining 方法检查)
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
String data1 = "Hello1";
if (byteBuffer.remaining() >= data1.length()) {
byteBuffer.put(data1.getBytes());
System.out.println("第 1 次添加数据:" + data1);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
} else {
System.out.println("第 1 次添加数据");
System.out.println("剩余空间不足,无法添加数据");
}
String data2 = "Hello2";
if (byteBuffer.remaining() >= data2.length()) {
byteBuffer.put(data2.getBytes());
System.out.println("第 2 次添加数据:" + data2);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
} else {
System.out.println("第 2 次添加数据");
System.out.println("剩余空间不足,无法添加数据");
}
# 输出结果
初始化
pos=0, remaining=10, limit=10
第 1 次添加数据:Hello1
pos=6, remaining=4, limit=10
第 2 次添加数据
剩余空间不足,无法添加数据
- 通过 try catch 捕获异常
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
try {
String data = "abcdefghijklmnopqrstuvwxyz";
byteBuffer.put(data.getBytes());
System.out.println("添加数据:" + data);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
} catch (BufferOverflowException e) {
e.printStackTrace();
System.out.println("添加数据失败");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
}
# 输出结果
初始化
pos=0, remaining=10, limit=10
java.nio.BufferOverflowException
添加数据失败
pos=0, remaining=10, limit=10