ByteBuffer getInt() 问题

发布于 2024-11-28 01:59:04 字数 608 浏览 2 评论 0原文

我们使用 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()会返回正确的值吗?

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

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

We are using Java ByteBuffer for socket communication with a C++ server. We know Java is Big-endian and Socket communication is also Big-endian. So whenever the byte stream received and put into a ByteBuffer by Java, we call getInt() to get the value. No problem, no conversion.

But if somehow we specifically set the ByteBuffer byte order to Little-endian (my co-worker actually did this),

  1. will the Java automatically convert the Big-endian into the Little-endian when the data is put into the ByteBuffer?

  2. Then the getInt() of the Little-endian version will return a right value to you?

I guess the answer to above two questions are yes. But when I try to verify my guessing and try to find how the getInt() works in ByteBuffer, I found it is an abstract method. The only subclass of ByteBuffer is the MappedByteBuffer class which didn't implement the abstract getInt(). So where is the implementation of the getInt() method?

For the sending, because we are using Little-endian ByteBuffer, we need to convert them into a Big-endian bytes before we put onto the socket.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

错々过的事 2024-12-05 01:59:04

ByteBuffer 将自动使用您指定的字节顺序。 (或者默认情况下为大端)

 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()); 

直接字节缓冲区和堆字节缓冲区都将按照您指定的方式重新排序字节。

ByteBuffer will automatically use the byte order you specify. (Or Big endian by default)

 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()); 

Both direct and heap ByteBuffers will re-order bytes as you specifiy.

蓝戈者 2024-12-05 01:59:04

那么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))));
}

上面的代码中,nativeByteOrder 和 bigEndian 是两个布尔成员,分别指示(并且有些冗余)配置的字节顺序是否: (a) 与本机字节顺序匹配; (b) 是大端字节序。

So where is the implementation of the getInt() method?

ByteBuffer is indeed an abstract class. There are several way in which byte buffers can be created:

In my JDK, these create instances of internal classes HeapByteBuffer and DirectByteBuffer. Their respective getInt functions are as follows:

// 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);
}

and

// 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))));
}

In the above, nativeByteOrder and bigEndian are two boolean members indicating respectively -- and somewhat redundantly -- whether the configured byte order: (a) matches the native byte order; (b) is big endian.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文