簡體   English   中英

協議緩沖區:如何將多個消息序列化和反序列化為文件(c ++)?

[英]protocol buffers: how to serialize and deserialize multiple messages into a file (c++)?

我是Protocol Buffers和c ++的新手,但我的任務要求我使用這兩個。 我想多次將數據結構(消息)寫入單個文件,並能夠讀取數據。 我可以讀取和寫入一條消息,但多條消息證明更難。 我已經找了幾個小時的答案,但我似乎無法將數據作為結構讀取。 任何示例代碼或指針都非常有用。

這是我的結構格式:

    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);

這些是我的.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似乎是我最好的選擇,但我找不到任何詳細的例子或解釋來幫助我理解。 我知道協議緩沖區不是自我划分的,這可能是我無法以原始格式讀回我的消息的原因。 任何幫助,將不勝感激。 謝謝

編輯:我已經嘗試使用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但它似乎沒有在文件中寫入任何內容。

我懷疑你的問題是你沒有刪除CodedOutputStreamFileOutputStream 這些對象緩沖輸出並在其析構函數中刷新緩沖區,因此如果您永遠不會銷毀它們,它們將不會寫入最后一個緩沖區,在這種情況下它是唯一的緩沖區。

我建議在堆棧上分配這些對象(作為局部變量)。 然后你不可能忘記摧毀它們。

有了這個,這里的代碼使用CodedInputStreamCodedOutputStream來讀/寫分隔的消息。 每條消息的前綴都是一個指示大小的varint,其格式與Java Protobuf庫的writeDelimitedTo() / parseDelimitedFrom() (一種從未進入C ++庫的特性)相同。

bool writeDelimitedTo(
    const google::protobuf::MessageLite& message,
    google::protobuf::io::ZeroCopyOutputStream* rawOutput) {
  google::protobuf::io::CodedOutputStream output(rawOutput);

  // Write the size.
  const int size = message.ByteSize();
  output.WriteVarint32(size);

  uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
  if (buffer != NULL) {
    // Optimization:  The message fits in one buffer, so use the faster
    // direct-to-array serialization path.
    message.SerializeWithCachedSizesToArray(buffer);
  } else {
    // Slightly-slower path when the message is multiple buffers.
    message.SerializeWithCachedSizes(&output);
    if (output.HadError()) return false;
  }

  return true;
}

bool readDelimitedFrom(
    google::protobuf::io::ZeroCopyInputStream* rawInput,
    google::protobuf::MessageLite* message) {
  google::protobuf::io::CodedInputStream input(rawInput);

  // Read the size.
  uint32_t size;
  if (!input.ReadVarint32(&size)) return false;

  // Tell the stream not to read beyond that size.
  auto limit = input.PushLimit(size);

  // Parse the message.
  if (!message->MergePartialFromCodedStream(&input)) return false;
  if (!input.ConsumedEntireMessage()) return false;

  // Release the limit.
  input.PopLimit(limit);

  return true;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM