gpt4 book ai didi

c# - 使用 protobuf CodedInputStream 读取 byte[]

转载 作者:行者123 更新时间:2023-11-30 23:05:51 30 4
gpt4 key购买 nike

在下面的代码中,我想在 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);
}

它失败了:

An unhandled exception of type 'Google.Protobuf.InvalidProtocolBufferException' occurred in Google.Protobuf.dll

Additional information: Protocol message contained an invalid tag (zero).

这种从 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

最佳答案

CodedOutputStreamCodedInputStream 主要供编译后的原型(prototype)类使用。 The API for CodedOutputStream声明这样并提到如果你想要手动编写代码调用这两个类中的任何一个,你需要在每个值之前使用它们的 WriteTag 方法。

但是,由于您希望使用 Google Protobuf 来序列化和解析任何 System.IO.Stream,因此可以按预期完成工作。 Protocol Buffer Basics for C#解析和序列化部分对此进行了很好的记录和描述。 . examples which can be found in Google Protobuf's Github对于快速掌握 Google Protobuf 的窍门非常有帮助。在那里您可以看到 MemoryStream 用于序列化对象,而 Parse.ParseFrom 方法可用于从序列化数据中解析对象。

正如您在问题的评论中提到的,using Google.Protobuf; 是能够使用 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);

关于c# - 使用 protobuf CodedInputStream 读取 byte[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48558451/

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