Scala中操作DirectByteBuffer时put写入不生效是什么原因?
问题原因
你代码的核心问题是使用def声明byteBuffer变量,def在Scala中代表方法定义,每次访问该变量都会重新执行一次ByteBuffer.allocateDirect(10 * 4)逻辑,生成一个全新的缓冲区实例。
你所有的putFloat、remaining、get操作实际都作用在不同的临时缓冲区对象上:
- 每次写入时都是在新分配的空缓冲区上执行put,操作完成后该临时对象就被丢弃,下一次访问
byteBuffer拿到的又是全新的空缓冲区,自然remaining始终返回40,写入的内容也不会保留 - 读取时同样每次都拿到新的空缓冲区,所以所有位置返回值都是0,get操作也不会改变位置信息
为什么HeapBuffer测试时看似正常
这和缓冲区类型没有关系,大概率是你测试HeapBuffer时使用的是val而非def声明变量:val是不可变变量,只会在声明时初始化一次,所有操作都作用在同一个实例上,逻辑自然符合预期。如果你把HeapBuffer的声明也改成def,会出现完全相同的异常现象。
修复方案
将变量声明从def修改为val即可:
// 把def改成val,只初始化一次缓冲区 val byteBuffer = ByteBuffer.allocateDirect(10 * 4) for (i <- 0 until 10) { println(s"Remaining: ${byteBuffer.remaining()}") byteBuffer.putFloat(1) } byteBuffer.position(0) for (i <- 0 until 40) { println(s"At index=$i, get=${byteBuffer.get()}") println(byteBuffer.remaining()) }
修改后put、get操作都会正常移动缓冲区的位置指针,读写逻辑也会符合预期。
内容的提问来源于stack exchange,提问作者user3761728
相关产品推荐
相关产品推荐

