当前位置: 首页 > ai >正文

Java 异常处理之 BufferUnderflowException(BufferUnderflowException 概述、常见发生场景、避免策略)

一、BufferUnderflowException 概述

  1. BufferUnderflowException 是 Java NIO 包中的一个运行时异常,是 RuntimeException 的子类
public class BufferUnderflowException extends RuntimeException {...
}
# 继承关系java.lang.Object-> java.lang.Throwable-> java.lang.Exception-> java.lang.RuntimeException-> java.nio.BufferUnderflowException
  1. 它发生在尝试从缓冲区读取比实际剩余更多的数据时,即缓冲区位置(position)已经到达或超过限制(limit)

二、常见发生场景

  1. 读取数据
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());int i1 = byteBuffer.getInt();// 读取 4 字节没问题
System.out.println("第 1 次读取:" + i1);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());int i2 = byteBuffer.getInt();// 再读取 4 字节没问题
System.out.println("第 2 次读取:" + i2);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());int i3 = byteBuffer.getInt(); // 再读取 4 字节,会抛出 BufferUnderflowException 异常
System.out.println("第 3 次读取:" + i3);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
# 输出结果初始化
pos=0, remaining=10, limit=10
第 1 次读取:0
pos=4, remaining=6, limit=10
第 2 次读取:0
pos=8, remaining=2, limit=10
Exception in thread "main" java.nio.BufferUnderflowException
  1. 批量读取数据
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());byte[] bytes = new byte[15];
byteBuffer.get(bytes);
System.out.println("读取数据:" + new String(bytes));
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
# 输出结果初始化
pos=0, remaining=10, limit=10
Exception in thread "main" java.nio.BufferUnderflowException
  1. 调用 flip 方法后,(批量)读取数据
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());String data = "abc";
byteBuffer.put(data.getBytes());
System.out.println("添加数据:" + data);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());byteBuffer.flip();
System.out.println("调用 flip 方法");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());byte[] bytes1 = new byte[2];
byteBuffer.get(bytes1);
System.out.println("第 1 次读取:" + new String(bytes1));
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());byte[] bytes2 = new byte[2];
byteBuffer.get(bytes2);
System.out.println("第 2 次读取:" + new String(bytes2));
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
# 输出结果初始化
pos=0, remaining=10, limit=10
添加数据:abc
pos=3, remaining=7, limit=10
调用 flip 方法
pos=0, remaining=3, limit=3
第 1 次读取:ab
pos=2, remaining=1, limit=3
Exception in thread "main" java.nio.BufferUnderflowException

三、避免策略

1、基本介绍
  1. 总是调用 remaining 方法检查剩余数据是否足够,不同的读取方法对读取长度有不同的要求
方法读取长度(字节)
byte get()1
char getChar()2
short getShort()2
int getInt()4
long getLong()8
float getFloat()4
double getDouble()8
ByteBuffer get(byte[] dst)dst.length
  1. 必要时,也可以通过 try catch 捕获异常
2、演示
  1. 读取数据(调用 remaining 方法检查)
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());int num = 1;
while (true) {if (byteBuffer.remaining() >= 4) {int i1 = byteBuffer.getInt();System.out.println("第 " + num + " 次读取:" + i1);System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());num++;} else {System.out.println("第 " + num + " 次读取");System.out.println("数据不足,无法读取");break;}
}
# 输出结果初始化
pos=0, remaining=10, limit=10
第 1 次读取:0
pos=4, remaining=6, limit=10
第 2 次读取:0
pos=8, remaining=2, limit=10
第 3 次读取
数据不足,无法读取
  1. 批量读取数据(调用 remaining 方法检查)
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());byte[] bytes = new byte[15];
if (byteBuffer.remaining() < bytes.length) {System.out.println("数据不足,无法读取");
} else {byteBuffer.get(bytes);System.out.println("读取数据:" + new String(bytes));System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
}
# 输出结果初始化
pos=0, remaining=10, limit=10
数据不足,无法读取
  1. 调用 flip 方法后,(批量)读取数据(调用 remaining 方法检查)
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());String data = "abc";
byteBuffer.put(data.getBytes());
System.out.println("添加数据:" + data);
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());byteBuffer.flip();
System.out.println("调用 flip 方法");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());byte[] bytes1 = new byte[2];
if (byteBuffer.remaining() < bytes1.length) {System.out.println("第 1 次读取");System.out.println("数据不足,无法读取");
} else {byteBuffer.get(bytes1);System.out.println("第 1 次读取:" + new String(bytes1));System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
}byte[] bytes2 = new byte[2];
if (byteBuffer.remaining() < bytes2.length) {System.out.println("第 2 次读取");System.out.println("数据不足,无法读取");
} else {byteBuffer.get(bytes2);System.out.println("第 2 次读取:" + new String(bytes2));System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
}
# 输出结果初始化
pos=0, remaining=10, limit=10
添加数据:abc
pos=3, remaining=7, limit=10
调用 flip 方法
pos=0, remaining=3, limit=3
第 1 次读取:ab
pos=2, remaining=1, limit=3
第 2 次读取
数据不足,无法读取
  1. 通过 try catch 捕获异常
ByteBuffer byteBuffer = ByteBuffer.allocate(10);
System.out.println("初始化");
System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());try {byte[] bytes = new byte[15];byteBuffer.get(bytes);System.out.println("读取数据:" + new String(bytes));System.out.println("pos=" + byteBuffer.position() + ", remaining=" + byteBuffer.remaining() + ", limit=" + byteBuffer.limit());
} catch (BufferUnderflowException 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.BufferUnderflowException
读取数据失败
pos=0, remaining=10, limit=10
http://www.xdnf.cn/news/6155.html

相关文章:

  • 华为云Flexus+DeepSeek征文|基于华为云ModelArts Studio平台体验DeepSeek-V3大模型
  • 微信小程序之按钮短时间内被多次点击问题
  • Python解释器、REPL与脚本的区别
  • TypeScript装饰器-简洁版
  • 启动窗体自动输入上次内容——CAD c#二次开发
  • MySQL--day1--数据库概述
  • [20250514] 脑机接口行业调研报告(2024年最新版)
  • Sunsetting 创建 React App
  • 斜率变化策略
  • 手写CString类
  • UniApp Vue3事件适配与兼容方案
  • python 练习 五
  • IIS服务器URL重写配置完整教程
  • MySQL视图:虚拟表的强大功能与应用实践
  • 国产化环境下的 DICOM 网络服务与影像处理适配
  • Yolov8的详解与实战-深度学习目标检测
  • 关于vue学习的经常性错误
  • KUKA库卡焊接机器人智能气阀
  • 亚远景-对ASPICE评估体系的深入研究与分析
  • ConfigMap 和 Secret 是否支持热更新
  • 系统单元测试和项目打包
  • Jmeter -- JDBC驱动连接数据库超详细指南
  • 东莞文件服务器存储维修-DELL MD3400电池故障
  • C++学习细节回顾(汇总二)
  • 基于Spring AI与Hugging Face TGI构建高效聊天应用:从配置到实践全解析
  • centos中postfix的作用
  • 用git下载vcpkg时出现Connection was reset时的处理
  • SpringBoot集成Kafka
  • Python × CARLA:如何在自动驾驶仿真世界里打造智能驾驶系统?
  • ansible进阶02