Java ByteBuffer - 在 put 调用链中相对重新定位?

标签 java bytebuffer

这就是我想要做的,除了它有两个问题:position() 执行绝对定位,而不是相对定位(因此 -1 的参数是非法的),并且您显然无法链接另一个方法调用在调用position()之后 - 编译器提示它无法识别putShort()。

// Method to create a packet header for sending a packet. The placement of the two numbers is
//  done according to little-endian encoding.
private byte[] createPacketHeader(EPacketType packetType, int fourBits,
                                  int totalMessageLength, int segmentSize) {

    return ByteBuffer.allocate(CPacketHeaderSize).order(ByteOrder.LITTLE_ENDIAN).
            put((byte) ((byte) (packetType.getValue() << 4) | (byte) fourBits)).
            putInt(totalMessageLength).  // Bottom 3 bytes of total length (+ 1 byte discarded)
            position(-1).  // Reposition to discard last byte from above call !!DOESN'T WORK!!
            putShort((short) segmentSize).  // Segment length
            put(_connectIdUtf8).  // Connection ID in UTF-8, should be <= 10 bytes
            array();  // This assumes zero initialization so final bytes are zero
}

这就是我目前正在做的事情。它确实有效,但与我希望我能做的相比似乎相当不优雅。

    ByteBuffer byteBuffer =
                     ByteBuffer.allocate(CPacketHeaderSize).order(ByteOrder.LITTLE_ENDIAN);

    byteBuffer.put((byte) ((byte) (packetType.getValue() << 4) | (byte) fourBits)).
            putInt(totalMessageLength).  // Bottom 3 bytes of total length (+ 1 byte discarded)
            position(byteBuffer.position() -1);  // Discard last byte from above call

    byteBuffer.putShort((short) segmentSize).  // Segment length
            put(_connectIdUtf8);  // Connection ID in UTF-8, should be <= 10 bytes

    return byteBuffer.array();  // This assumes zero initialization so final bytes are zero

关于如何回到更接近第一次尝试的事情,有什么建议吗?

编辑: 感谢您的回答,他们都很有帮助。如果有人好奇,这就是我最终所做的:

// Method to create a packet header for sending a packet. The placement of the two numbers is
//  done according to little-endian encoding.
private byte[] createPacketHeader(EPacketType packetType, int fourBits,
                                  int totalMessageLength, int segmentSize) {

    return ByteBuffer.allocate(CPacketHeaderSize).order(ByteOrder.LITTLE_ENDIAN).
            put((byte) ((byte) (packetType.getValue() << 4) | (byte) fourBits)).
            put(intToThreeBytes(totalMessageLength)).  // Bottom 3 bytes of total length
            putShort((short) segmentSize).  // Segment length
            put(_connectIdUtf8).  // Connection ID in UTF-8, should be <= 10 bytes
            array();  // This assumes zero initialization so final bytes are zero
}


// Method to convert an int into a three-byte byte array, using little-endian encoding
private byte[] intToThreeBytes(int aNumber) {
    byte[] byteArray = new byte[3];
    for (int i = 0; i < 3; i++)
        byteArray[i] = (byte)(aNumber >> i * 8);
    return byteArray;
}

最佳答案

也缺少优雅:

byte[] bytes = ByteBuffer.allocate(4).putInt(totalMessageLength).array();
byteBuffer.put(bytes, 0, 3);

关于Java ByteBuffer - 在 put 调用链中相对重新定位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18017455/

相关文章:

java - 如何在通用类型的 gson 上使用自定义反序列化?

java - Android:在网格中显示文本的简单 GridView

java - 逐个字符翻译字符串

c++ - std::string 与字节缓冲区(c++ 中的区别)

android - CopyPixelsFromBuffer 有效。但解码其 ByteArray 返回 null

java - 在网站页面上实现 Android/iPhone 应用程序

java String.valueOf 问题

java - 将包含ascii字符串的byte[]快速转换为int/double/date等,无需new String

java - ByteBuffer 和 FileChannel 只读取指定数量的字节

Java 音频字节缓冲区需要不同的时间来填充