读写5字节数据:如何使写入整数与读取结果一致的技术问题
问题分析与解决方案
看起来你在字节缓冲区的数值读取和组合上踩了两个常见的位运算坑,我帮你拆解一下:
1. getUnsignedShort()方法的运算优先级错误
你当前的getUnsignedShort()实现里,位运算的优先级搞反了。255 << 8的优先级比&高,导致代码实际执行的是byteArray[position++] & (255 << 8),这会错误地清零低8位;而且后续的+ byteArray[position++] & 255也因为优先级问题,先执行加法再做按位与,结果完全不符合预期。
正确的实现应该先把每个字节转成无符号整数(& 0xFF),再做移位和组合:
public int getUnsignedShort() { // 先读高位字节,转无符号 int highByte = byteArray[position++] & 0xFF; // 再读低位字节,转无符号 int lowByte = byteArray[position++] & 0xFF; // 高位左移8位,和低位做位或(比加法更安全,避免意外进位) return (highByte << 8) | lowByte; }
2. 数值组合时的移位位数错误
你现在用val1 << 32来组合,但val1是无符号短整型(16位),后面跟着的是3字节整数(24位),两者加起来是5字节数据。如果是按**大端字节序(先读高位)**写入的,那么val1应该占据结果的高16位,val2占据低24位,正确的移位应该是左移24位,而不是32位。
另外还要确保get3ByteInt()能正确读取无符号的3字节数值(避免符号扩展导致负数),比如:
public long get3ByteInt() { int b1 = byteArray[position++] & 0xFF; int b2 = byteArray[position++] & 0xFF; int b3 = byteArray[position++] & 0xFF; // 转成long再移位,防止int溢出 return ((long)b1 << 16) | ((long)b2 << 8) | b3; }
最后组合的代码修改为:
long val1 = (long) buffer.getUnsignedShort(); long val2 = buffer.get3ByteInt(); // val1左移24位,和val2做位或,得到正确的组合值 long result = (val1 << 24) | val2;
举个实际例子:假设你写入的原始数值是0x1234567890(5字节),其中0x1234是unsigned short,0x567890是3字节整数。用上面的代码组合后,result会是0x1234567890,和原始数值完全一致;而之前左移32位的写法会得到0x123400567890,明显不对。
内容的提问来源于stack exchange,提问作者Palidino
相关产品推荐
相关产品推荐

