协议缓冲区:如何将多条消息序列化和反序列化到一个文件(c+;+;)中? 我对协议缓冲区和C++是新的,但是我的任务要求我使用这两个。我想将数据结构(消息)多次写入单个文件,并能够读取数据。我可以读写一条信息,但多条信息更难。我已经寻找了几个小时的答案,但我似乎无法将数据作为一个结构来阅读。任何示例代码或指针都将非常有用

协议缓冲区:如何将多条消息序列化和反序列化到一个文件(c+;+;)中? 我对协议缓冲区和C++是新的,但是我的任务要求我使用这两个。我想将数据结构(消息)多次写入单个文件,并能够读取数据。我可以读写一条信息,但多条信息更难。我已经寻找了几个小时的答案,但我似乎无法将数据作为一个结构来阅读。任何示例代码或指针都将非常有用,c++,structure,protocol-buffers,C++,Structure,Protocol Buffers,这是我的结构的格式: typedef struct Entry { char name[ NAME_MAX]; int id; int age; char DoB[32]; } entry; 这就是我用来写入文件的内容: Person_File file; fstream output("file", ios::out | ios::trunc |

这是我的结构的格式:

    typedef struct Entry
       {
          char  name[ NAME_MAX];
          int   id;
          int   age;
          char  DoB[32]; 
       } entry;
这就是我用来写入文件的内容:

    Person_File file;
    fstream output("file", ios::out | ios::trunc | ios::binary);
    file.SerializeToOstream(&output);
我尝试将文件编辑选项更改为“追加”而不是“截断”,但这不允许我以所需的格式读取数据

这是我用来阅读的:

    fstream input("file", ios::in | ios::binary);
    file.ParseFromIstream(&input);
以下是my.proto文件的内容:

    message Person {


message File {
    required string pname =1;
    required int32 id =2;
    required int32 age =3;
    required string DoB =4;
}

repeated File file =1;
}

从我所做的所有搜索来看,CodedInputStream/CodedOutputStream似乎是我最好的选择,但我还没有找到任何详细的例子或解释来帮助我理解。我知道协议缓冲区不是自定界的,这可能就是我无法以原始格式读回消息的原因。 任何帮助都将不胜感激。谢谢

编辑: 我根据收到的消息尝试使用CodeDoutpStream,但它似乎没有向文件中写入任何内容

    int fd = open("file.txt",O_WRONLY | O_APPEND | O_CREAT);

    FileOutputStream* file_ostream_ = new FileOutputStream(fd);
    CodedOutputStream* ostream_ = new CodedOutputStream(file_ostream_);


ostream_->WriteLittleEndian32(file.ByteSize());
    file.SerializeToCodedStream(ostream_);
使用此代码后,文件将显示为空白。我哪里做错了

根据收到的消息,我尝试使用CodedOutputStream,但没有成功 似乎没有在文件中写入任何内容

    int fd = open("file.txt",O_WRONLY | O_APPEND | O_CREAT);

    FileOutputStream* file_ostream_ = new FileOutputStream(fd);
    CodedOutputStream* ostream_ = new CodedOutputStream(file_ostream_);


ostream_->WriteLittleEndian32(file.ByteSize());
    file.SerializeToCodedStream(ostream_);
我怀疑您的问题在于您没有删除
CodedOutputStream
FileOutputStream
。这些对象在其析构函数中缓冲输出并刷新缓冲区,因此如果您从未销毁它们,它们将不会写入最后一个缓冲区,在本例中,最后一个缓冲区是唯一的缓冲区

我建议在堆栈上分配这些对象(作为局部变量)。那你就不可能忘记摧毁它们

下面是使用
CodedInputStream
codedOutStream
读取/写入分隔消息的代码。每个消息都用一个指示ValIt的前缀来表示,它的大小与java原代码库的<>代码> WrdEdEdItEDIT() PARSELIDIMIDEFROM()/<代码>(一个从未进入C++库的特性)相同。
文件
变量的定义在哪里?我不知道协议缓冲区库,但我知道您可以使用
std::fstream。write
使用
sizeof(Entry)
条目
写入文件,然后使用
std::fstream.read
。。这是一个豆荚结构。它应该不需要任何特殊的库。我已经添加了文件的定义。最简单的方法是在消息之前写入大小;看一看,宾果!!!。删除CodedOutputStream和FileOutputStream成功了。感谢您的出色回答我假设
rawOutput
必须使用size
消息初始化。ByteSize()+sizeof(size)
,对吗?@kakyo大多数流类型不需要预先指定大小。如果您是专门序列化到字节数组中,那么我不建议使用分隔格式——这种格式的要点是支持将多条消息写入流。但是要直接回答您的问题,不,
message.ByteSize()+sizeof(size)
是不正确的。您需要
message.ByteSize()+google::protobuf::io::codedOutStream::computeRawVarint32Size(大小)