Google Protobuf 使用教程

Google Protobuf是一种平台无关,语言无关的结构化数据编解码协议,类似JSON或者XML,与这两者不同的是Protobuf采用的是二进制编解码方式,二JSON和XML是文本编解码,因此同样大小的结构化数据,经Protobuf编码之后更加轻量,这篇博客进行了详尽的阐述并且进行了比较。但是知道了Protobuf是什么之后,似乎还是不明白Protobuf到底怎么用,什么时候用,这就是写下本文的目的:使用Protobuf

Protocol Buffer Basics(C++ 和 Python):

本文旨在解释利用google Protobuf 进行数据的编解码应用,文中使用的message采用官方教程中的地址簿,本教程参考
How to use Protobuf for data interchange,原文使用Go和Java语言来展示不同语言的编解码过程,而本文采用自己更加常用的C++和Python语言进行编解码过程。

利用Protobuf在不同平台和不同语言间的数据传输过程

Google Protobuf 使用教程_第1张图片
Protobu编解码过程
  • 根据具体的使用场景编写特定的.proto文件(完整代码)
syntax = "proto3";

package example;//package name for avoiding name conflict

message Person{
    string name =1;//encoding suquence length
    float height = 2;//encoding fixed length
    int32 age = 3;////encoding varint length
    
    repeated PhoneNumber phones = 5;//"repeated" indicate that the "Person" message consists of repeated (none or more) "PhoneNumber" message 
    
    message PhoneNumber
    {
        string number = 1;
        int32 type = 2;
    }

}
message AddressBook
{
    repeated Person people = 1;
}
  • 将.proto生成特定语言能够使用的数据结构
protoc --cpp_out=. example.proto  //生成example.pb.h 和example.pb.cc文件
protoc --python_out=. example.proto  //生成example_pb2.python文件
  • C++利用自动生成的数据结构代码进行数据编码(代码片段),Protobuf采用的是字节流编解码,因此相比于XML和JSON格式的编解码占用更小的存储,这个博客对这三种编码格式进行了比较。本文中是将编码后的二进制文件保存在本地(encoding_cpp.pbuf),然后使用Python读取该文件,这一过程与网络传输的过程类似。(完整代码)
//fill velues of data
    example::AddressBook address_book;
    example::Person *person = address_book.add_people();
    person->set_name("zhanghy");
    person->set_age(27);
    person->set_height(180.0);

    example::Person_PhoneNumber *number = person->add_phones();
    number->set_number("18700000000");
    number->set_type(1);

    //encoding data and write to local file(the same approach would be used to write the data to the output stream of a network connection.)
    std::fstream f_out("../encoding_cpp.pbuf", std::ios::out | std::ios::trunc | std::ios::binary);
    if (!address_book.SerializePartialToOstream(&f_out))
    {
        std::cerr << "Failed to write adress book" << std::endl;
    }
  • 利用Pythond解析本地文件(encoding_cpp.pbuf)并且打印(完整代码)
import example_pb2

if __name__ == "__main__":
    file_name = "./encoding_cpp.pbuf"
    address_book_from_file = example_pb2.AddressBook()
    with open(file_name,"rb") as f:
        address_book_from_file.ParseFromString(f.read())

    print(address_book_from_file)

运行结果:


Google Protobuf 使用教程_第2张图片
运行结果

你可能感兴趣的