如何在Kotlin中将ULong写入ByteBuffer?
解决Kotlin中ByteBuffer写入无符号类型的思路
嘿,这个问题我之前做二进制序列化的时候也碰到过!ByteBuffer本身确实没有提供putULong、putUInt这类直接操作无符号类型的方法,但核心原因是无符号类型和对应有符号类型的底层二进制位模式完全兼容,我们可以利用这一点轻松搞定,给你几个实用的方案:
方案1:直接转换为对应有符号类型写入
因为ULong和Long都是8字节、UShort和Short都是2字节,它们的底层二进制存储完全一致,只是程序对数值的解读逻辑不同。所以我们可以把无符号类型转成对应有符号类型,用原生的putXxx方法写入,读取时再转回来即可。
举个ULong的例子:
// 写入ULong val uLongVal: ULong = 9876543210987654321UL byteBuffer.putLong(uLongVal.toLong()) // 读取ULong(注意要保证读取位置正确) byteBuffer.position(0) // 重置读取位置 val readULong = byteBuffer.getLong().toULong()
这种方式完全不会丢失数据,是最直接高效的做法。
方案2:给ByteBuffer扩展无符号类型操作方法
为了让代码风格更统一,你可以给ByteBuffer写几个扩展函数,模拟原生putXxx的用法,用起来更顺手:
// 扩展写入方法 fun ByteBuffer.putULong(value: ULong): ByteBuffer = putLong(value.toLong()) fun ByteBuffer.putUInt(value: UInt): ByteBuffer = putInt(value.toInt()) fun ByteBuffer.putUShort(value: UShort): ByteBuffer = putShort(value.toShort()) fun ByteBuffer.putUByte(value: UByte): ByteBuffer = putByte(value.toByte()) // 扩展读取方法 fun ByteBuffer.getULong(): ULong = getLong().toULong() fun ByteBuffer.getUInt(): UInt = getInt().toUInt() fun ByteBuffer.getUShort(): UShort = getShort().toUShort() fun ByteBuffer.getUByte(): UByte = getByte().toUByte()
之后使用的时候就和原生方法一样自然:
byteBuffer.putULong(123456789UL) val myULong = byteBuffer.getULong()
额外注意点
- 确保ByteBuffer的**字节顺序(Byte Order)**统一:不管是写入还是读取,要保持大端(Big Endian)或小端(Little Endian)一致,比如
byteBuffer.order(ByteOrder.LITTLE_ENDIAN),否则会出现数值解析错误。 - 其他无符号类型(UByte、UShort、UInt)都可以套用同样的逻辑,本质都是利用位模式兼容的特性。
内容的提问来源于stack exchange,提问作者abeat
相关产品推荐
相关产品推荐

