繁体   English   中英

C ++ protobuf:如何通过“SerializeToOstream()”将多个消息写入文件

[英]C++ protobuf: how to write multiple messages into file by “SerializeToOstream()”

我发现当我使用SerializeToOstream()时,只有最后一条消息被写入文件,之前的消息都被以后的调用覆盖。 像这样:

我是你的hello.proto:

message hello
{
    required int32 f1=1;
    required int32 f2=2;
    optional int32 f3=3;
}

然后我编译并在一个cpp文件中使用它:

#include "hello.pb.h"
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
    fstream fo("./hello.data",ios::binary|ios::out);
    hello p1,p2,p3;
    p1.set_f1(1);
    p1.set_f2(2);
    p2.set_f1(3);
    p2.set_f2(4);
    p3.set_f1(5);
    p3.set_f2(6);
    p1.SerializeToOstream(&fo);
    p2.SerializeToOstream(&fo);
    p3.SerializeToOstream(&fo);
    fo.close();

    fstream fi("./hello.data",ios::binary|ios::in);
    hello pi;
    pi.ParseFromIstream(&fi);
    cout<<pi.f1()<<pi.f2()<<endl;
    return 0;
}

好吧,我发现只有“p3”被写入这个“hello.data”,p1和p2被覆盖了某种方式?

为什么protobuf只写最后一条消息? 我们通常使用protobuf来传递多条消息,对吧? 那么如何将多条消息写入一个文件? 如何纠正我的程序?

这里的问题是协议缓冲区不是自定界限的; 要解析一条消息,您必须事先知道要读取多少字节。 由于有线格式的工作方式,您可以连接两个(或更多)序列化协议缓冲区,但仍然有一个有效的消息; 对于任何给定的奇异域,后面的值优先于先前的值。 所以发生的事情是ParseFromIstream正在读取所有三个序列化消息,就像它们是一条消息一样,并且最后一条消息实际上优先于前两条消息。

要解决此问题,您必须为每条消息包含某种消息长度前缀。 通常,这是通过为每个消息添加一个存储其长度的varint来完成的。 这个来自Kenton Varda的代码是一个很好的例子,说明如何在C ++中做到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM