使用protobuf-net发布反序列化(protocolBuffer)序列化数据

本文关键字:protocolBuffer 序列化 数据 反序列化 protobuf-net 使用 | 更新日期: 2023-09-27 18:13:09

我使用protobuf-net序列化数据,并且能够在c#中设计相同的。

放一个c#假人w#

var file = File.Create("animal.bin");
//Creating Msg - Fill the Data
animal.id = "1";
animal.Name = "Rat";
animal.host = "Cheetha";
ProtoBuf.Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 1);
animal.id = "2";
animal.Name = "Cat";
animal.host = "Cheetha";
ProtoBuf.Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 1);
....
animal.id = "4";
animal.name = "Cheetha";
animal.host = "Cheetha";
ProtoBuf.Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 1);
//Done Creating Msg
file.Close();

到目前为止还好…这里没有问题。但是,当我试图在c++中使用协议缓冲区反序列化时,我无法获得正确的数据

<标题> cpp代码…
GOOGLE_PROTOBUF_VERIFY_VERSION; 
string fpath = "animal.bin";
fstream input(fpath, ios::in | ios::binary);
if (!input)
{
    cerr << "failed to open " << fpath << endl;
    return false;
}
ZeroCopyInputStream *raw_in = new IstreamInputStream(&input);
CodedInputStream *coded_in = new CodedInputStream(raw_in);
google::protobuf::uint32 n;
std::string tmpStr;
animal::animalInfo animalList;
coded_in->ReadVarint32(&n);
cout << "# " << n << endl;  //output: #10
coded_in->ReadRaw(&tmpStr,n); //tmpStr shows data like >>1..Rat..Ch 
animalList.ParseFromArray(&tmpStr,1);//Not sure if this is correct usage?

我确信我犯了一个错误,但不能理解错在哪里....我读了又读了很多关于这方面的文章,但还是看不出有什么问题

使用协议Buffer2.5, protobuf-netR622, Visual Studio 2010

使用protobuf-net发布反序列化(protocolBuffer)序列化数据

我想你只是标题不匹配;一个长度前缀字段头(字段1)是两个 "varint"s;第一个 "varint"将始终是十进制10(10表示:字段1,长度前缀)。第二个"变量"告诉您下一个数据的长度。所以-如果你想手动解码它你会称ReadVarint32时间。我不熟悉ReadRaw,但如果第二个参数是要读取的字节数,那么它会到那里,即

coded_in->ReadVarint32(&n); // field header
// assert: n === 10
coded_in->ReadVarint32(&n); // length
coded_in->ReadRaw(&tmpStr,n);

或者,只使用包装器对象-即

message animals {
    repeated animal items = 1;
}

和反序列化它作为animals 的一个实例-这使用完全相同的布局。这里唯一的区别是,它将一次加载所有项-因此,如果您正在读取非常长的流,可能会出现问题。

另一种替代方法是:不要添加字段头:

Serializer.SerializeWithLengthPrefix(file, animal, PrefixStyle.Base128, 0);

那么你只会读到一个"varint":

coded_in->ReadVarint32(&n); // length
coded_in->ReadRaw(&tmpStr,n);