2011-08-04 74 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都会按照您指定的顺序重新排序字节。