gpt4 book ai didi

java - 如何使用 Java 将 INT32 打包到我的 MessagePack 中?

转载 作者:太空宇宙 更新时间:2023-11-04 10:58:48 24 4
gpt4 key购买 nike

我遇到了一个问题,我需要将 INT32 发送到另一个应用程序,但根据我的阅读,messagepack.putIntmessagepack.putLong 将尝试将其优化为 UINT32,这会给接收应用程序带来问题。

接收应用程序给我错误消息

decode error, skipping message. msgp: attempted to decode type "uint" with method for "int"

我正在使用带有依赖项的 Maven

  <dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-core</artifactId>
<version>0.8.13</version>
</dependency>

其他人也遇到了同样的问题,并表示解决方案如下

好的,所以我们发现了问题,看起来 metricTank 要求将消息对象的 time 属性序列化为 INT32,但是 packInt(或 packLong)总是会尝试将其优化为 metricTank 不喜欢的 UINT32。所以我们必须使用 addPayload 并序列化 MessagePacker.Code.INT32,然后是实际的 4 个字节的 time 属性。

但我不确定该怎么办,也无法联系 OP。

我尝试了以下方法,但不起作用

ByteBuffer buf = ByteBuffer.allocate(1 + Long.BYTES);
buf.put(MessagePack.Code.INT32);
buf.putLong(md.time);
packer.addPayload(buf.array());

bytes 数组长度需要为 5,第一个字节是 header,即 0xd2,其他 4 个字节需要是值

 ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(md.time);
dos.close();
byte[] longBytes = baos.toByteArray();

ByteBuffer lBytes = ByteBuffer.allocate(4);
for (int i = 0; i < 4; i++) {
lBytes.put(longBytes[i]);
}

ByteBuffer buf = ByteBuffer.allocate(5);
buf.put((byte) 0xd2);
buf.put(lBytes.array());

这不会产生错误,但接收时的时间值不正确。

有人可以告诉我如何将 INT32 而不是 UINT32 打包到我的 MessagePack 中,或者告诉我如何以正确的方式打包数据,以便在接收应用程序上正确解包数据吗?

<小时/>

接收应用程序写在 Go并使用 tinylib msgp解码数据的库

// ReadInt64Bytes tries to read an int64
// from 'b' and return the value and the remaining bytes.
// Possible errors:
// - ErrShortBytes (too few bytes)
// - TypeError (not a int)
func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
l := len(b)
if l < 1 {
return 0, nil, ErrShortBytes
}

lead := b[0]
if isfixint(lead) {
i = int64(rfixint(lead))
o = b[1:]
return
}
if isnfixint(lead) {
i = int64(rnfixint(lead))
o = b[1:]
return
}

switch lead {
case mint8:
if l < 2 {
err = ErrShortBytes
return
}
i = int64(getMint8(b))
o = b[2:]
return

case mint16:
if l < 3 {
err = ErrShortBytes
return
}
i = int64(getMint16(b))
o = b[3:]
return

case mint32:
if l < 5 {
err = ErrShortBytes
return
}
i = int64(getMint32(b))
o = b[5:]
return

case mint64:
if l < 9 {
err = ErrShortBytes
return
}
i = getMint64(b)
o = b[9:]
return

default:
err = badPrefix(IntType, lead)
return
}
}

这会检查第一个字节,如果第一个字节等于 mint32,即 0xd2,则读取接下来的四个字节,这是使用 getmint32 得到的 long 值

func getMint32(b []byte) int32 {
return (int32(b[1]) << 24) | (int32(b[2]) << 16) | (int32(b[3]) << 8) | (int32(b[4]))
}

最佳答案

在此特定问题中,接收应用程序必须接收 INT32,并且字节数组的长度需要为 5。第一个字节是标题 0xd2,如 OP 中所示。这告诉解码方法它是 INT32。接下来的 4 个 4 字节是时间值。

我忘记了 long 是 8 个字节,所以我们只需要使用纪元时间,它是一个整数。

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt((int)(md.time/1000));
dos.close();
byte[] timeBytes = baos.toByteArray();


ByteBuffer buf = ByteBuffer.allocate(5);
buf.put((byte) 0xd2);//header
buf.put(timeBytes);//time value (int32 bytes not uint32)

关于java - 如何使用 Java 将 INT32 打包到我的 MessagePack 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47121532/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com