【发布时间】:2015-09-25 10:04:10
【问题描述】:
我使用 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 double cumQty = 7;
required double lastPx = 8;
required double avgPx = 9;
optional string lastCapacity = 10;
required int64 transactionTime = 11;
required int64 reportTime = 12;
在构建类并使用测试数据填充这些字段后,我将使用 .toByteArray() 方法将其转换为字节数组:
double d = 99.0;
FillProto fillProto = FillProto.newBuilder()
.setTid(n)
.setClOrdID("ClOrdID")
.setExecID("ExecID")
.setTicketType("ticketType")
.setLastMkt("LastMkt")
.setLastQty(d)
.setCumQty(d)
.setLastPx(d)
.setAvgPx(d)
.setLastCapacity("LastCapacity")
.setTransactionTime(now.getTime())
.setReportTime(now.getTime())
.build();
Log.info(class_,method_,"Sending through:\n" + new String(fillProto.toByteArray()));
我通过 Solace 队列发送 ByteArray,在另一端消费后,我尝试使用 FillProto.parseFrom(byte[]) 构建另一个对象,但出现错误:“在解析协议消息时,输入意外地在田野中间结束。”。 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 )`.....)
【问题讨论】:
-
new String(fillProto.toByteArray())可能会做出可怕的事情。不要像这样将随机原型转储到String中,使用某种编码。除此之外——99.0在其 IEEE 754 二进制表示中确实有许多零位。会这样吗? -
同意路易斯。你有任何证据表明这种编码不正确吗?
-
我将字节数组作为字节消息通过 Solace 队列。当我在另一端使用它并尝试使用 FillProto.parseFrom(byte[]) 创建另一个 FillProto 对象时,我收到一个错误,即输入在字段中间意外结束。从读取另一个线程看来,这可能是由字节数组中的空值引起的(使用 msg.dump 输出)。我正在通过这个队列的其他没有任何双打的原型对象正在另一边重建良好。
-
没关系,原来我没有为那个特定的原型使用 .parseFrom(byte[])。我有一个 if 语句,根据检索到的数据类型将代码分成不同的路径,并且该特定块尚未从旧方法更新。完全是用户错误。
标签: java serialization double protocol-buffers