2011-08-04 118 views
4

我們使用的是Java字節緩衝區與一個C++服務器socket通訊。我們知道Java是Big-endian,Socket通信也是Big-endian。所以每當字節流被Java接收並放入一個ByteBuffer時,我們就調用getInt()來獲取值。沒問題,沒有轉換。字節緩衝區getInt()問題

但是,如果不知何故,我們專門設置字節緩衝區的字節順序到小端(我的同事其實這樣做),

  1. 將在Java大端會自動轉換成小端時數據放入ByteBuffer?

  2. 隨後的小端版本調用getInt()將一個正確的價值回報給你?

我想上面兩個問題的答案是肯定的。但是,當我嘗試驗證我的猜測並嘗試查找getInt()如何在ByteBuffer中工作時,我發現它是一種抽象方法。 ByteBuffer的唯一子類是沒有實現抽象getInt()的MappedByteBuffer類。那麼getInt()方法的實現在哪裏?

對於發送,因爲我們使用的是小端字節緩衝區,我們需要將它們轉換成大端字節之前我們把到插座。

+0

我看到的Java 6字節緩衝區的兩個實現()實現getInt。它們是java.nio.DirectByteBuffer和java.nio.HeapByteBuffer。快速瀏覽一下HeapByteBuffer看起來好像它可以像你期望的那樣處理字節順序。 – Joshua

+0

套接字通信是什麼意思?在下,即TCP/UDP ...etc是big endian,但你發送的數據取決於你如何在平臺上放置它。 – roni

+1

你有超過40個問題沒有被接受的答案。也許你可以跟進答案,以便他們可以被接受。 –

回答

2

那麼,是調用getInt()方法的實現?

ByteBuffer確實是一個抽象類。有幾種方法可以創建字節緩衝區:

在我的JDK中,這些創建內部類HeapByteBufferDirectByteBuffer的實例。它們各自的getInt功能如下:

// HeapByteBuffer 

public int getInt() { 
    return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian); 
} 

public int getInt(int i) { 
    return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian); 
} 

// DirectByteBuffer 

private int getInt(long a) { 
    if (unaligned) { 
     int x = unsafe.getInt(a); 
     return (nativeByteOrder ? x : Bits.swap(x)); 
    } 
    return Bits.getInt(a, bigEndian); 
} 

public int getInt() { 
    return getInt(ix(nextGetIndex((1 << 2)))); 
} 

public int getInt(int i) { 
    return getInt(ix(checkIndex(i, (1 << 2)))); 
} 

在上文中,nativeByteOrderbigEndian是指示分別兩個布爾成員 - 和有點冗餘 - 是否所配置的字節順序:( a)匹配本地字節順序; (b)是大端。

8

的ByteBuffer會自動使用指定的字節順序。 (或默認爲big endian)

ByteBuffer bb = 
// to use big endian 
bb.order(ByteOrder.BIG_ENDIAN); 

// to use little endian 
bb.order(ByteOrder.LITTLE_ENDIAN); 

// use the natural order of the system. 
bb.order(ByteOrder.nativeOrder()); 

直接和堆ByteBuffers都會按照您指定的順序重新排序字節。