2013-06-25 4 views
1

файл .proto:Какой формат хранения данных protobuf?

package lm; 
message helloworld 
{ 
    required int32 id = 1; 
    required string str = 2; 
    optional int32 opt = 3; 
} 

writer.cc файл:

#include <iostream> 
#include <string> 
#include "lm.helloworld.pb.h" 
#include <fstream> 
using namespace std; 

int main() 
{ 
    lm::helloworld msg1; 
    msg1.set_id(101000); 
    msg1.set_str("helloworld,this is a protobuf writer"); 
    fstream output("log", ios::out | ios::trunc | ios::binary); 
    string _data; 
    msg1.SerializeToString(&_data); 
    cout << _data << endl; 
    if(!msg1.SerializeToOstream(&output)) 
    { 
     cerr << "Failed to write msg" << endl; 
     return -1; 
    } 
    return 0; 
} 

файл reader.cc:

#include <iostream> 
#include <fstream> 
#include <string> 
#include "lm.helloworld.pb.h" 
using namespace std; 

void ListMsg(const lm::helloworld & msg) 
{ 
    cout << msg.id() << endl; 
    cout << msg.str() << endl; 
} 

int main(int argc, char* argv[]) 
{ 
    lm::helloworld msg1; 
    { 
     fstream input("log", ios::in | ios::binary); 
     if (!msg1.ParseFromIstream(&input)) 
     { 
      cerr << "Failed to parse address book." << endl; 
      return -1; 
     } 
    } 

    ListMsg(msg1); 
    return 0; 
} 

Это простой читатель и писатель модель с использованием Protobuf. но что в журнале - это читаемая строка, набранная в файле write.cc вместо «числового формата», почему?

ответ

1

The encoding is described here.

Без примера того, что выходит из другого конца, то есть немного трудно точно ответить, но есть два возможных объяснения того, что вы видите:

  1. вы явно перешедшие в TextFormat в коде ; это очень маловероятно - и в самом деле, основное использование 10 - отладка и т. д.
  2. гораздо более вероятно, вы просто видите текстовые данные из вашего сообщения в двоичном формате; текст кодируется как UTF-8, так что если вы открываете файл Protobuf в текстовом редакторе, части его появится достаточно читаемой, чтобы отобразить что-то в файле

Реальный вопрос: какова фактические байты в вашем выходном файле? Если это что-то вроде:

08-88-95-06-12-24-68-65-6C-6C-6F-77-6F-72-6C-64-2C-74-68- 69-73-20-69-73-20-61-20-70-72-6F-74-6F-62-75-66-20-77-72-69-74-65-72

тогда - двоичный формат; но отметить, что большинство, что это просто UTF-8, строки "helloworld,this is a protobuf writer" - которая доминирует сообщение от огромных размеров:

68-65-6C-6C-6F-77-6F-72-6C-64 -2c-74-68-69-73-20-69-73-20-61-20-70-72-6F-74-6F-62-75-66-20-77-72-69-74-65 -72

так что, если вы смотрите в любом текстовом редакторе, он будет выглядеть как несколько бессмысленных символов в начале, за которым следуют разборчиво helloworld,this is a protobuf writer.

"двоичной" здесь бит на старте:

08-88-95-06-12-24

Это:

  • 08: заголовок: поле 1, varint
  • 88-95-06: значение (десятичное) 101000 как varint
  • 12: header: fie л.д. 2, длина префикса
  • 24: значение (десятичное) 36 в качестве varint (длина строки в байтах)

ключевые моменты отметить:

  • если ваш сообщение доминирует над текстом, да, большие его части будут выглядеть удобочитаемыми даже в двоичной форме
  • посмотреть на накладные расходы; он до 6 байтов для кодирования всего остального сообщения, а 3 байта - данные (101000) - поэтому только 3 байта были фактически потеряны как накладные расходы; теперь сравните и сравните с xml, json и т. д., чтобы понять, что делает protobuf, чтобы помочь вам
+0

спасибо, у меня есть тот же результат с шестнадцатеричным режимом в vim – nzomkxia

Смежные вопросы