Protocol Buffers是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台并且可扩展性极强。现阶段官方支持C++、JAVA、Python等三种编程语言,但可以找到大量的几乎涵盖所有语言的第三方拓展包。
Protocol Buffers经常被简称为protobuf。
GitHub地址:https://github.com/google/protobuf
谷歌官方文档:https://developers.google.com/protocol-buffers/
安装方法:现在GitHub上下载Release的Python版本,我使用Ubuntu系统,解压后执行安装命令:
$ ./configure $ make $ sudo make install
安装后测试protoc命令,该程序用于把proto文件翻译成目标代码:
$ protoc --version $ libprotoc 3.0.0
安装完后需要安装python支持,我采用pip安装:
$ sudo pip install --upgrade protobuf
这样就可以了。
然后编写一个最简单的proto文件:test_proto.proto
syntax = "proto2"; message Person { }
相当于定义了一个结构Person,但是没有任何成员,使用编译命令把它转成python代码:
$ protoc --python_out=./ ./test_proto.proto
自动生成了一个test_proto_pb2.py:
# Generated by the protocol buffer compiler. DO NOT EDIT! # source: test_proto.proto import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='test_proto.proto', package='', syntax='proto2', serialized_pb=_b('\n\x10test_proto.proto\"\x08\n\x06Person') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) _PERSON = _descriptor.Descriptor( name='Person', full_name='Person', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, syntax='proto2', extension_ranges=[], oneofs=[ ], serialized_start=20, serialized_end=28, ) DESCRIPTOR.message_types_by_name['Person'] = _PERSON Person = _reflection.GeneratedProtocolMessageType('Person', (_message.Message,), dict( DESCRIPTOR = _PERSON, __module__ = 'test_proto_pb2' # @@protoc_insertion_point(class_scope:Person) )) _sym_db.RegisterMessage(Person) # @@protoc_insertion_point(module_scope)
然而我们使用的时候不用关心这个文件,修改.proto文件,重新编译即可。
在test_proto.proto中加个变量试试:
syntax = "proto2"; message Person { required string name = 1; }
编译以后,生成的代码和上一版本做个比较:
主要就是在fields里增加了内容。
有了fields,我们就可以用来存数据了,主要使用SerializeToString()和ParseFromString()来序列化和反序列化数据结构,最简单的示例:
from test_proto_pb2 import Person FILE_PATH = './my_person.raw' def write_test(): person = Person() person.name = 'my name is hello world!!!' f = open(FILE_PATH, "wb") f.write(person.SerializeToString()) f.close() def read_test(): person = Person() f = open(FILE_PATH, "rb") person.ParseFromString(f.read()) f.close() print person.name if __name__ == "__main__": write_test() read_test()
Protocol Buffer协议可以用来将数据存文件,当然主要用于网络传输数据,采用二进制的形式传输不易被破解,还节省流量,因为几乎没有可读性。