簡體   English   中英

Java 字節緩沖區行為

[英]Java Byte Buffer behavior

我只是在玩 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"
    }
}

上面的程序應該打印“Hell”,但它沒有。 但是如果我在put()調用中從 1 開始給出位置,那么它就起作用了,為什么?

您的代碼和執行該任務的方法存在一些問題:

  1. 沒有顯式索引的put()方法將更新緩沖區位置。 在四次放置操作之后,緩沖區位置為 4。
  2. asCharBuffer()重用原始緩沖區的內容,從原始緩沖區中的當前位置開始,即 4 並且原始緩沖區沒有從該位置開始的實際數據。
  3. 在一系列put操作之后嘗試執行get操作之前, flip()確實是正確的操作,但是:
  4. 在 Java 中, char是一個兩字節值,這意味着你原來的 4 字節緩沖區將被解釋為一個 2 字符緩沖區,例如第一個字符的值將是( char ) ( ( ( ( byte ) 'H' ) << 8 ) + ( byte ) 'e' )

除此之外, ByteBuffer行為完全符合預期並在其 javadoc 中記錄。

解決編碼問題的示例:

ByteBuffer byteBuffer = ByteBuffer.allocate( 100 );
byteBuffer
        // explicitly converting each char into 2 bytes
        .put( ( byte ) ( 'H' >>> 8 ) ).put( ( byte ) 'H' ) 
        .put( ( byte ) ( 'e' >>> 8 ) ).put( ( byte ) 'e' )
        .put( ( byte ) ( 'l' >>> 8 ) ).put( ( byte ) 'l' )
        .put( ( byte ) ( 'l' >>> 8 ) ).put( ( byte ) 'l' )
        .put( ( byte ) ( 'o' >>> 8 ) ).put( ( byte ) 'o' );
// flipping the buffer to be able access the current content via get operations
byteBuffer.flip();
// reinterpreting the byte sequence as a char sequence
CharBuffer charBuffer = byteBuffer.asCharBuffer();
System.out.println( charBuffer.toString() );

問題是 char 是 16 位,而 byte 是 8 位。 當你投射時,你會丟失一些信息。 您需要為每個字符插入兩個字節,然后翻轉緩沖區,如下所示:

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"
 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM