Protobuf双打序列化为空字节

时间:2015-07-07 18:35:50

标签: 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 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                               )`.....)

1 个答案:

答案 0 :(得分:3)

这很正常。使用标准的8字节IEEE-754表示来表示双打。双值零表示为全零,大多数其他值也包含零。

听起来您的消息传递基础架构设计用于在NUL终止的文本字符串上运行。此类基础结构不适用于原始Protobuf内容,因为它将在第一个NUL字节处截断消息。通常,您不能在为文本设计的上下文中使用原始Protobuf数据,因为可能会发生各种损坏。请特别注意,永远不要将protobuf字节传递给new String(),因为String存储Unicode文本,而不是字节。

如果您需要在需要文本的地方传输Protobufs,则需要对数据进行base64编码以防止此类损坏 - base64允许将原始字节放置在文本上下文中,但会增加数据的整体大小33%。