如何将CharBuffer转换为字符串?调用toString()无法获取预期"hi"值的问题咨询
CharBuffer转换为字符串:为什么你的代码得不到"hi"?
刚好碰到过类似的问题,我来给你详细拆解一下你的代码问题,以及正确的解决方法。
先分析你的代码为什么没得到预期结果
你写的代码是:
val a = CharBuffer.allocate(10); a.put('h'); a.put('i'); val b = a.toString();
问题出在CharBuffer的toString()方法的行为上:它返回的不是缓冲区里所有已写入的字符,而是当前position到limit之间的字符序列。
执行完两次put后:
a的position已经移动到了2(每次put都会把position加1,指向接下来要写入的位置)limit还是初始的10(默认等于容量,代表最多能访问的位置)
所以此时调用toString(),会读取从索引2到9的字符——这部分都是缓冲区初始化时默认填充的'\u0000'(空字符),自然得不到你想要的"hi"。
执行代码后的变量状态
- 变量
a:这是一个容量为10的HeapCharBuffer,状态为:position = 2(下一个写入位置)limit = 10(最大访问位置)capacity = 10(总容量)
缓冲区内容:索引0是'h',索引1是'i',索引2到9全是'\u0000'。
- 变量
b:是由索引2到9的空字符组成的字符串,看起来像是空字符串或包含不可见字符的内容,完全不符合预期。
正确获取目标字符串的方法
这里有两种通用且可靠的方式:
方法1:用flip()切换到读取模式
flip()是NIO缓冲区的核心方法之一,它会:
- 将
limit设置为当前的position(也就是你已经写入的字符数量) - 将
position重置为0(指向缓冲区起始位置)
这样就把缓冲区从写入模式切换到了读取模式,此时调用toString()就会读取从0到limit(也就是2)的字符,刚好是你写入的"hi":
val a = CharBuffer.allocate(10) a.put('h') a.put('i') a.flip() // 关键:切换到读取模式 val b = a.toString() // 此时b的值就是"hi"
方法2:直接截取底层数组(仅限HeapBuffer)
如果你确定使用的是allocate()创建的堆缓冲区(不是直接缓冲区),可以直接获取底层字符数组,然后指定起始索引和长度:
val a = CharBuffer.allocate(10) a.put('h') a.put('i') // 从数组起始位置截取,长度为已写入的字符数(a.position()的值是2) val b = String(a.array(), 0, a.position())
⚠️ 注意:如果是CharBuffer.allocateDirect()创建的直接缓冲区,调用array()会抛出UnsupportedOperationException,所以方法1的通用性更强。
额外补充
不要用rewind()来替代flip()——rewind()只会把position重置为0,但不会修改limit,此时toString()会读取从0到10的所有字符(包括后面的8个空字符),得到的是"hi"加上一堆不可见字符,这不是你想要的结果。
内容的提问来源于stack exchange,提问作者Damn Vegetables
相关产品推荐
相关产品推荐

