【问题标题】:ByteBuffer getInt() questionByteBuffer getInt() 问题
【发布时间】:2011-08-04 15:08:22
【问题描述】:

我们使用 Java ByteBuffer 与 C++ 服务器进行套接字通信。我们知道 Java 是 Big-endian,而 Socket 通信也是 Big-endian。所以每当Java接收到字节流并将其放入ByteBuffer中时,我们都会调用getInt()来获取值。没问题,没有转化。

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

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

  2. 那么小端版本的getInt()会返回一个正确的值给你吗?

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

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

【问题讨论】:

  • 我在 Java 6 中看到了两个实现 getInt() 的 ByteBuffer。它们是 java.nio.DirectByteBuffer 和 java.nio.HeapByteBuffer。快速浏览一下 HeapByteBuffer 看起来它确实可以按您的预期处理字节顺序。
  • socket通信是什么意思?底层,即 TCP/UDP...等是大端,但您发送的数据取决于您如何放置它以及在平台上。
  • 您有 40 多个问题没有得到接受的答案。也许您可以跟进答案,以便他们可以被接受。
  • '我猜以上两个问题的答案是肯定的。'很难理解为什么会以其他方式提供该设施。

标签: java nio bytebuffer endianness


【解决方案1】:

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

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

【讨论】:

    【解决方案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) 是大端。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-22
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      相关资源
      最近更新 更多