ByteBuffer读取Uint24触发IndexOutOfBoundsException,求解决方法
解决Uint24读取的IndexOutOfBounds问题及正确实现方式
首先咱们先理清几个关键问题,这是你出错的核心根源:
- 你提到的Uint24是3字节的无符号整数,不是2字节(如果是2字节无符号类型,那是Uint16);
bb.getDouble()是用来读取8字节双精度浮点数的API,和读取整数完全不匹配,这也是你抛出IndexOutOfBoundsException的直接原因——你的字节数组长度根本不够8字节,ByteBuffer尝试读取超出限制的字节自然会报错;- 读取单字节应该用
bb.get(),而不是bb.getShort()——getShort()是读取2字节的有符号短整型,用它读单字节属于用错了API。
正确读取小端序Uint24的代码实现
既然你设置了ByteOrder.LITTLE_ENDIAN(小端序,低字节在前),我们需要依次读取3个字节,再组合成无符号的24位整数(Java没有原生的Uint24类型,用32位的int存储完全足够):
ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); // 读取3个字节,注意Java的byte是有符号的,需要转成无符号值再计算 byte lowByte = bb.get(); byte midByte = bb.get(); byte highByte = bb.get(); // 小端序下,第一个读取的lowByte是最低8位,midByte是中间8位,highByte是最高8位 int uint24Value = ((highByte & 0xFF) << 16) | ((midByte & 0xFF) << 8) | (lowByte & 0xFF);
如果你实际要处理的是2字节Uint16(可能笔误)
如果是你描述有误,实际需要处理的是2字节的无符号整数,那代码会更简单:
ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); short signedShort = bb.getShort(); // 将有符号short转成无符号的int(Java没有原生Uint16类型) int uint16Value = signedShort & 0xFFFF;
补充:读取单字节的正确方式
你之前用bb.getShort()读单字节是错误的,正确读取单字节并转成无符号值的代码是:
byte signedByte = bb.get(); int unsignedByteValue = signedByte & 0xFF;
内容的提问来源于stack exchange,提问作者cole
相关产品推荐
相关产品推荐

