ByteBuffer getInt()问题

时间:2011-08-04 15:08:23

标签: java nio bytebuffer endianness

我们正在使用Java ByteBuffer与C ++服务器进行套接字通信。我们知道Java是Big-endian,而Socket通信也是Big-endian。因此,只要字节流被Java接收并放入ByteBuffer,我们就会调用getInt()来获取值。没问题,没有转换。

但是如果我们以某种方式将ByteBuffer字节顺序专门设置为Little-endian(我的同事实际上已经这样做了),

  1. 当数据放入ByteBuffer时,Java会自动将Big-endian转换为Little-endian吗?

  2. 那么Little-endian版本的getInt()会给你一个正确的值吗?

  3. 我想上面两个问题的答案是肯定的。但是当我尝试验证我的猜测并试图找到getInt()在ByteBuffer中的工作原理时,我发现它是一个抽象方法。 ByteBuffer的唯一子类是MappedByteBuffer类,它没有实现抽象的getInt()。那么getInt()方法的实现在哪里?

    对于发送,因为我们使用的是Little-endian ByteBuffer,我们需要在放入套接字之前将它们转换为Big-endian字节。

2 个答案:

答案 0 :(得分:9)

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将按照您的指定重新排序字节。

答案 1 :(得分:3)

  

那么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)是大端。