Java Protobuf将序列化加倍为空字节
我使用Google Protobuf 2.6.1创建了一个非常简单的java类,其结构如下:Java Protobuf将序列化加倍为空字节,java,serialization,double,protocol-buffers,Java,Serialization,Double,Protocol Buffers,我使用Google Protobuf 2.6.1创建了一个非常简单的java类,其结构如下: required int64 tid = 1; required int64 tid = 1; required string clOrdID = 2; required string execID = 3; required string ticketType = 4; optional string lastMkt = 5; required double lastQty = 6; required
required int64 tid = 1;
required int64 tid = 1;
required string clOrdID = 2;
required string execID = 3;
required string ticketType = 4;
optional string lastMkt = 5;
required double lastQty = 6;
required double cumQty = 7;
required double lastPx = 8;
required double avgPx = 9;
optional string lastCapacity = 10;
required int64 transactionTime = 11;
required int64 reportTime = 12;
在构建类并用测试数据填充这些字段之后,我将使用.toByteArray()方法将其转换为字节数组:
我将BytErrar通过一个缓冲队列发送出去,在另一方消耗之后,我尝试使用FILPROTO .PARSEON(Byth[])构建另一个对象,但是得到一个错误:“当解析协议消息时,输入在一个字段中间意外终止。”ByteArray看起来不错,直到标记为double的字段都输出为null(00字节)。有人知道这里发生了什么吗
字节数组如下: 08 05 12 07 63 6c 4f 72 64 49 44 1a 06 65 78 65 ....clOrdID..exe
63 49 44 22 0a 74 69 63 6b 65 74 54 79 70 65 2a cID".ticketType*
07 6c 61 73 74 4d 6b 74 31 00 00 00 00 00 c0 58 .lastMkt1......X
40 39 00 00 00 00 00 c0 58 40 41 00 00 00 00 00 @9......X@A.....
c0 58 40 49 00 00 00 00 00 c0 58 40 52 0c 4c 61 .X@I......X@R.La
73 74 43 61 70 61 63 69 74 79 58 b0 8b a8 ce e6 stCapacityX.....
29 60 b0 8b a8 ce e6 29 )`.....)
这是正常的。双精度使用标准的8字节IEEE-754表示法表示。双值零表示为全零,大多数其他值也将包含零 听起来,您的消息传递基础结构设计用于对以NUL结尾的文本字符串进行操作。这样的基础设施将无法处理原始Protobuf内容,因为它将在第一个NUL字节截断消息。通常,您不能在为文本设计的上下文中使用原始Protobuf数据,因为可能会发生各种损坏。请特别注意,永远不要将protobuf字节传递给
new String()
,因为String
存储的是Unicode文本,而不是字节
如果需要在需要文本的地方传输Protobufs,则需要对数据进行base64编码以防止此类损坏——base64允许将原始字节放置在文本上下文中,但会将数据的总大小增加33%。这是正常的。双精度使用标准的8字节IEEE-754表示法表示。双值零表示为全零,大多数其他值也将包含零 听起来,您的消息传递基础结构设计用于对以NUL结尾的文本字符串进行操作。这样的基础设施将无法处理原始Protobuf内容,因为它将在第一个NUL字节截断消息。通常,您不能在为文本设计的上下文中使用原始Protobuf数据,因为可能会发生各种损坏。请特别注意,永远不要将protobuf字节传递给
new String()
,因为String
存储的是Unicode文本,而不是字节
如果需要在需要文本的地方传输Protobufs,则需要对数据进行base64编码以防止此类损坏——base64允许将原始字节放在文本上下文中,但会将数据的总体大小增加33%。
新字符串(fillProto.toByteArray())
可能会造成可怕的后果。不要像那样将随机proto转储到字符串中,使用某种编码。除此之外--99.0
在其IEEE 754二进制表示中有许多零位。是吗?同意路易斯的说法。你有证据表明这种编码不正确吗?我正在通过Solace队列将字节数组作为字节消息传递。当我在另一端消耗它并尝试创建另一个FILPROTO对象时,使用FILPROTO .PARSEOF(Byth[]),我得到一个错误,输入在一个字段中间意外终止。从读取另一个线程来看,这似乎是由字节数组中的空值(使用msg.dump输出)引起的。我正在通过这个队列的其他没有任何双精度的proto对象在另一端重建得很好。我有一个if语句,根据检索到的数据类型将代码分为不同的路径,而这个特定的块并没有从旧方法中更新。完全是用户错误。新字符串(fillProto.toByteArray())
可能会造成可怕的后果。不要像那样将随机proto转储到字符串中,使用某种编码。除此之外--99.0
在其IEEE 754二进制表示中有许多零位。是吗?同意路易斯的说法。你有证据表明这种编码不正确吗?我正在通过Solace队列将字节数组作为字节消息传递。当我在另一端消耗它并尝试创建另一个FILPROTO对象时,使用FILPROTO .PARSEOF(Byth[]),我得到一个错误,输入在一个字段中间意外终止。从读取另一个线程来看,这似乎是由字节数组中的空值(使用msg.dump输出)引起的。我正在通过这个队列的其他没有任何双精度的proto对象在另一端重建得很好。我有一个if语句,根据检索到的数据类型将代码分为不同的路径,而这个特定的块并没有从旧方法中更新。完全是用户错误。
08 05 12 07 63 6c 4f 72 64 49 44 1a 06 65 78 65 ....clOrdID..exe
63 49 44 22 0a 74 69 63 6b 65 74 54 79 70 65 2a cID".ticketType*
07 6c 61 73 74 4d 6b 74 31 00 00 00 00 00 c0 58 .lastMkt1......X
40 39 00 00 00 00 00 c0 58 40 41 00 00 00 00 00 @9......X@A.....
c0 58 40 49 00 00 00 00 00 c0 58 40 52 0c 4c 61 .X@I......X@R.La
73 74 43 61 70 61 63 69 74 79 58 b0 8b a8 ce e6 stCapacityX.....
29 60 b0 8b a8 ce e6 29 )`.....)