Java Byte Buffer行为

时间:2014-05-23 06:24:51

标签: java nio

我刚刚使用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开始的位置那么它有效吗,为什么?

2 个答案:

答案 0 :(得分:5)

您的代码和处理该任务的方法中存在一些问题:

    没有显式索引的
  1. put()方法将更新缓冲区位置。在四次放置操作之后,缓冲位置为4。
  2. asCharBuffer()重用原始缓冲区的内容,从原始缓冲区中的当前位置开始,该位置为4,原始缓冲区没有从该位置开始的实际数据。
  3. flip()确实是在get一系列操作后尝试执行put操作之前的正确操作,但是:
  4. 在Java中,char是一个双字节值,这意味着原始的4字节缓冲区将被解释为2字符缓冲区,例如第一个字符的值将为{{1} }。
  5. 除此之外,( 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"
 }
}