Protocol Buffers 是一種輕便高效的結構化數據存儲格式,能夠用於結構化數據串行化,或者說序列化。它很適合作數據存儲或數據交換格式。可用於通信協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。目前提供了 C++、Java、Python 三種語言的 API。ios
protobuf協議是以一個 .proto 後綴的文件爲基礎,這個文件經過結構化數據類型的形式描述了一個數據信息。c++
protobuf的序列化底層原理:多線程
you can see, each field in the message definition has a unique numbered tag. These tags are used to identify your fields in the message binary format, and should not be changed once your message type is in use. Note that tags with values in the range 1 through 15 take one byte to encode. Tags in the range 16 through 2047 take two bytes. So you should reserve the tags 1 through 15 for very frequently occurring message elements. Remember to leave some room for frequently occurring elements that might be added in the future.框架
翻譯爲:
protobuf協議使用二進制格式表示Key字段;對value而言,不一樣的類型採用的編碼方式也不一樣,若是是整型,採用二進制表示;若是是字符,會直接原樣寫入文件或者字符串(不編碼)。ide
公式 field_number << 3)| wire_type
,若是域號大於等於16,兩個字節共16位,去掉移位的3位,去掉兩個字節中第一個比特位, 總共16個比特位只有16-5==11個比特位用來表示Key,因此Key的域號要小於2^11== 2048。ui
T - L - V 的數據存儲方式編碼
正式由於採用PB自身框架代碼和編譯器完成和獨特的編碼方式,纔會使protobuf的序列化緊湊,效率這麼高。spa
最初的目錄結構:
線程
各文件內容:翻譯
cat helloworld.proto
syntax = "proto2"; package lm; message helloworld { required int32 id = 1; required string str = 2; optional int32 opt=3; }
cat main.cpp
#include <iostream> #include <fstream> #include "protoc_dir/helloworld.pb.h" using namespace std; void ListMsg(const lm::helloworld & msg){ cout << msg.id()<<endl; cout << msg.str()<<endl; } int main(void) { lm::helloworld msg1; lm::helloworld msg2; msg1.set_id(101); //設置id msg1.set_str("helloworld"); //設置字符串 { fstream output("./tst.log", ios::out |ios::trunc |ios::binary); if (!msg1.SerializeToOstream(&output)){ cerr << "failed to serialize msg1" <<endl; return -1; } } { fstream input("./tst.log",ios::in|ios::binary); if (!msg2.ParseFromIstream(&input)){ cerr << "failed to parse" <<endl; return -1; } ListMsg(msg2); } return 0; }
1.根據.proto文件生成.cc .h文件
protoc --cpp_out=./protoc_dir/ helloworld.proto
2.編譯源代碼
g++ -std=c++11 main.cpp protoc_dir/helloworld.pb.cc -lprotobuf -lpthread -o obj_run
注意: protobuf用到了多線程, 因此必定要加上 lpthread
3.運行可執行文件