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

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.dtcms.com/a/190992.html

相关文章:

  • C 语言学习笔记(8)
  • 因果推断 | 用SHAP分值等价因果效应值进行反事实推理
  • 【Linux】掌握 setsid:让进程脱离终端独立运行
  • 东芝新四款产品“TB67Z830SFTG、TB67Z830HFTG、TB67Z850SFTG、TB67Z850HFTG系列三相栅极驱动器ic三相栅极驱动器IC
  • 软件测试--入门
  • 【Linux】Ext系列文件系统
  • 鸿蒙-5.1.0-release构建编译环境
  • Oracle中的select1条、几条、指定范围的语句
  • 每日算法-250514
  • 【golang】网络数据包捕获库 gopacket
  • 嵌入式系统中WAV音频文件格式详解与处理实践
  • 【CustomPagination:基于Vue 3与Element Plus的高效二次封装分页器】
  • Lightpanda开源浏览器:专为 AI 和自动化而设计的无界面浏览器
  • 安卓基础(Bitmap)
  • scons user 3.1.2
  • C#强类型枚举的入门理解
  • C++【STL】(2)string
  • 4级流程控制
  • 复现:DemoGen 用于数据高效视觉运动策略学习的 合成演示生成 (RSS) 2025
  • Docker 常见问题及其解决方案
  • nginx报错-[emerg] getpwnam(“nginx“) failed in /etc/nginx/nginx.conf:2
  • FastAPI + OpenAI 模型 的 GitHub 项目结构模板
  • 未来软件开发趋势与挑战
  • Python+Selenium爬虫:豆瓣登录反反爬策略解析
  • C#调用C++dll 过程记录
  • 【VS】VS2019中使用rdlc报表,生成之前修改XML
  • 【每天一个知识点】模型轻量化(Model Compression and Acceleration)技术
  • 解释 RESTful API
  • 数据结构学习之链表学习:单链表
  • Linux笔记---信号(中)