使用protobuf CodedInputStream从byte []中读取

时间:2018-02-01 08:38:50

标签: c# protocol-buffers

在下面的代码中,我想在c#中使用预定义的protobuf消息。我发现我能够编写并使用该方法来获取已创建的方法并生成byte[]

 ContainerMessage containerMessage = new ContainerMessage();
 containerMessage.Type = CommandType.Connect;
 containerMessage.Connect = new Connect();
 containerMessage.Connect.ClientName = "TemporaryClientName";

 byte[] stream = new byte[containerMessage.CalculateSize()];   
 using (Google.Protobuf.CodedOutputStream outstream = new Google.Protobuf.CodedOutputStream(stream))
 {
     containerMessage.WriteTo(outstream);
 }

这可以按预期工作,我可以检查消息,并且值与byte[]中的值一样符合预期。但是如果我尝试反序列化我刚刚创建的这个简单的byte[]

  using (Google.Protobuf.CodedInputStream instream = new Google.Protobuf.CodedInputStream(stream))
  {
      instream.ReadMessage(containerMessage);
  }

失败了:

  

未处理的类型' Google.Protobuf.InvalidProtocolBufferException'发生在Google.Protobuf.dll

     

附加信息:协议消息包含无效标记(零)。

这种反序列化的方式是byte[]正确的protobuf吗?

Protobuf定义是:

message ContainerMessage {
    CommandType type = 1;
    bool commandSuccess = 2;

    oneof message {
        Connect connect = 3;
    }
}

enum CommandType {
    START = 0;
    CONNECT = 2;
}

message Connect {
    string ClientName = 1;
    uint32 PushPullPort = 2;
}

使用命令行生成CS文件:

protoc.exe -I=%CD% --csharp_out=..\GeneratedCsMessaging\ Connect.proto

1 个答案:

答案 0 :(得分:2)

CodedInputStreamWriteTag主要用于编译的proto类。 The API for CodedOutputStream声明如果你想要手动编写代码来调用这两个类中的任何一个,你需要在每个值之前使用它们的MemoryStream方法。

但是,由于您希望使用Google Protobuf来序列化和解析任何System.IO.Stream,它将按照预期的方式完成工作。这是非常详细的文档,并在Protocol Buffer Basics for C#解析和序列化部分中进行了描述。 examples which can be found in Google Protobuf's Github对于快速掌握Google Protobuf非常有帮助。在那里,您可以看到Parse.ParseFrom用于序列化对象,而using Google.Protobuf;方法可用于从序列化数据中解析对象。

正如您在评论中提到的那样 byte[] serializedBytes; ContainerMessage containerMessage = new ContainerMessage() { Connect = new Connect() { ClientName = "TemporaryClientName", }, Type = CommandType.Connect, }; using( MemoryStream stream = new MemoryStream()) { containerMessage.WriteTo(stream); serializedBytes = stream.ToArray(); } ContainerMessage parsedCopy = ContainerMessage.Parser.ParseFrom(serializedBytes); 是能够使用Google Protobuf功能的重要部分。

编辑:您案例中的示例用法可能类似于此

#navigationBar{
    display:block;
    position:fixed;
    background-color: black;
    width:100%; 
    height:70px;
    z-index:0; 
}
#after-nav{
   position:relative;
   z-index:-1;
   padding-top: 70px;
}