Java direct ByteBuffer-解码字符
我希望将字节读入direct ByteBuffer,然后在不将原始缓冲区重新写入byte[]数组的情况下对其进行解码,以最小化内存分配 因此,我希望避免使用Java direct ByteBuffer-解码字符,java,encoding,nio,bytebuffer,direct-buffer,Java,Encoding,Nio,Bytebuffer,Direct Buffer,我希望将字节读入direct ByteBuffer,然后在不将原始缓冲区重新写入byte[]数组的情况下对其进行解码,以最小化内存分配 因此,我希望避免使用StandardCharsets.UTF_8.decode(),因为它在堆上分配新数组 我被困在如何解码字节上。考虑下面的代码,该代码将字符串写入缓冲区,然后再次读取ID。 ByteBuffer byteBuffer = ByteBuffer.allocateDirect(2 << 16); byteBuffer.put("He
StandardCharsets.UTF_8.decode()
,因为它在堆上分配新数组
我被困在如何解码字节上。考虑下面的代码,该代码将字符串写入缓冲区,然后再次读取ID。
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(2 << 16);
byteBuffer.put("Hello Dávid".getBytes(StandardCharsets.UTF_8));
byteBuffer.flip();
CharBuffer charBuffer = byteBuffer.asCharBuffer();
for (int i = charBuffer.position(); i < charBuffer.length(); i++) {
System.out.println(charBuffer.get());
}
如何解码缓冲区?您不能指定
字符缓冲区的编码。请看这里:
另外,由于缓冲区是可变的,我不知道如何从中创建一个始终不可变的字符串,而不进行内存重新分配
我希望将字节读入direct ByteBuffer,然后在不将原始缓冲区重新写入byte[]数组的情况下对其进行解码,以最小化内存分配
ByteBuffer.asCharBuffer()
确实适合您的需要,因为两个包装器共享相同的底层缓冲区
这个方法的意思是:
新缓冲区的位置将为零,其容量和限制将为该缓冲区中剩余的字节数除以2
虽然没有明确说明,但这是一个提示,CharBuffer
在给定的缓冲区上使用UTF-16字符编码。由于我们无法控制charbuffer使用的编码方式,因此除了在该编码方式中写入字符字节之外,您没有太多选择
byteBuffer.put(“Hello Dávid”.getBytes(StandardCharsets.UTF_16));
关于打印for
循环的一点。请注意,CharBuffer.length()
实际上是缓冲区位置和限制之间剩余的字符数,因此它会随着调用CharBuffer.get()
而减少。因此,您应该使用get(int)
或将
终止条件的更改为limit()
谢谢你,约翰,但我的问题仍然有效。如何在没有额外内存分配的情况下解码direct ByteBuffer中的字符?您的问题是如何指定direct CharBuffer中的编码?
但是…我想这应该是一个注释,还是一个重复的接近投票,而不是一个anwser。正如我在回答中已经说过的,您不能这样做,因为Java中的String
是不可变的,因此如果没有副本,您就不可能这样做(否则您可以通过修改缓冲区来修改String
。)公平地说,它将重新表述。我对读取单个字符比对整个字符串更感兴趣。您需要翻转字符缓冲区,
而不是字节缓冲区。
字符缓冲区不继承翻转状态。
䡥汬漠