我刚刚使用Java ByteBuffers,并且不明白为什么输出不正确。
import java.nio.ByteBuffer;
public class TestBuffers {
public static void main(String[] args) {
ByteBuffer byteBuffer = ByteBuffer.allocate(100);
byteBuffer.put((byte)'H').put((byte)'e').put((byte)'l').put((byte)'l');
System.out.println(byteBuffer.asCharBuffer().toString()); // should print "Hell"
}
}
上述程序应该打印“地狱”,但事实并非如此。但如果我在put()
电话中给出从1开始的位置那么它有效吗,为什么?
答案 0 :(得分:5)
您的代码和处理该任务的方法中存在一些问题:
put()
方法将更新缓冲区位置。在四次放置操作之后,缓冲位置为4。asCharBuffer()
重用原始缓冲区的内容,从原始缓冲区中的当前位置开始,该位置为4,原始缓冲区没有从该位置开始的实际数据。flip()
确实是在get
一系列操作后尝试执行put
操作之前的正确操作,但是:char
是一个双字节值,这意味着原始的4字节缓冲区将被解释为2字符缓冲区,例如第一个字符的值将为{{1} }。除此之外,( char ) ( ( ( ( byte ) 'H' ) << 8 ) + ( byte ) 'e' )
的行为完全符合预期并记录在其javadoc中。
修复编码问题的示例:
ByteBuffer
答案 1 :(得分:4)
问题是char是16位,字节是8位。当你施放时,你会失去一些信息。您需要为每个char插入两个字节,然后翻转缓冲区,如下所示:
import java.nio.ByteBuffer;
public class TestBuffers {
ByteBuffer byteBuffer = ByteBuffer.allocate(100);
byteBuffer.put((byte) ('H' & 0xFF00)).put((byte) ('H' & 0x00FF)).put((byte) ('E' & 0xFF00))
.put((byte) ('E' & 0x00FF)).put((byte) ('L' & 0xFF00)).put((byte) ('L' & 0x00FF))
.put((byte) ('L' & 0xFF00)).put((byte) ('L' & 0x00FF));
byteBuffer.flip();
System.out.println(byteBuffer.asCharBuffer().toString()); // should print "Hell"
}
}