本文共 3611 字,大约阅读时间需要 12 分钟。
Protobuf(Protocol Buffers)是一种轻量级、高效的结构化数据存储格式。它平台无关、语言无关,并且支持扩展,广泛应用于通信协议和数据存储等领域。与传统的XML相比,Protobuf的解析速度快约20-100倍,序列化后的数据量也只有XML的1/3到1/10,极大地降低了数据传输和存储的成本。
在安装前,确保系统已预装以下软件:
autoconf automake libtool curl make g++ unzip
./autogen.sh./configuremakemake checksudo make install
// addressbook.protosyntax = "proto2";package addressbook;message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4;}message AddressBook { repeated Person person_info = 1;} protoc -I=$SRC_DIR --cpp_out=$DST_DIR addressbook.proto
#include "addressbook.pb.h"#includeusing namespace std;int main() { AddressBook person; Person* pi = person.add_person_info(); pi->set_name("aut"); pi->set_id(1219); cout << "before clear(), id = " << pi->id() << endl; pi->clear_id(); cout << "after clear(), id = " << pi->id() << endl; pi->set_id(1087); if (!pi->has_email()) { pi->set_email("autyinjing@126.com"); } PhoneNumber* pn = pi->add_phone(); pn->set_number("021-8888-8888"); pn = pi->add_phone(); pn->set_number("138-8888-8888"); pn->set_type(Person::MOBILE); uint32 size = person.ByteSize(); unsigned char byteArray[size]; person.SerializeToArray(byteArray, size); AddressBook help_person; help_person.ParseFromArray(byteArray, size); Person help_pi = help_person.person_info(0); cout << "*****************************" << endl; cout << "id: " << help_pi.id() << endl; cout << "name: " << help_pi.name() << endl; cout << "email: " << help_pi.email() << endl; for (int i = 0; i < help_pi.phone_size(); ++i) { auto help_pn = help_pi.mutable_phone(i); cout << "phone_type: " << help_pn->type() << endl; cout << "phone_number: " << help_pn->number() << endl; } cout << "*****************************" << endl; return 0;}
基本操作:
TypeName xxx() const;bool has_xxx();void set_xxx(const TypeName& value);void clear_xxx();重复字段:
TypeName* add_xxx();TypeName xxx(int index) const;TypeName* mutable_xxx(int index);int xxx_size();序列化与反序列化:
bool SerializeToOstream(std::ostream* output) const;bool SerializeToString(std::string* output) const;bool SerializeToArray(void* data, int size) const;bool ParseFromIstream(std::istream* input);bool ParseFromString(const std::string& data);bool ParseFromArray(const void* data, int size);其他:
bool IsInitialized();size_t ByteSize() const;(n << 1) ^ (n >> 31)(或(n << 1) ^ (n >> 63))。field_number和wire_type组成。wire_type决定了字段的编码方式。| Type | Meaning | Used For |
|---|---|---|
| 0 | Varint | int32, int64, uint32, uint64, sint32, sint64, bool, enum |
| 1 | 64-bit | fixed64, sfixed64, double |
| 2 | Length-delimited | string, bytes, embedded messages, packed repeated fields |
| 3 | Start group | groups (废弃) |
| 4 | End group | groups (废弃) |
| 5 | 32-bit | fixed32, sfixed32, float |
| 6 | Fixed32 | fixed32, sfixed32, float |
| 7 | Fixed64 | fixed64, sfixed64, double |
Protobuf在处理小型消息时效率非常高,但对于大块数据(超过1MB)其表现并不理想。因此,合理使用Protobuf,确保消息大小在合理范围内。
本文介绍了Protobuf的基本使用方法和编码规则,涵盖了从安装到实际应用的全过程。更多高级功能,如反射机制、扩展、Oneof等,建议参考官方文档深入研究。
转载地址:http://fgxfk.baihongyu.com/