from:http://blog.163.com/typhoon_1986/blog/static/678877802011910102113393/ 序列化王道之protobuf 開發某些分佈式系統時,經常使用的功能之一就是要在進程之間交互數據,固然,你能夠用管道,shared memory,嵌入式數據庫, in memory db等。但使用這些方式傳送數據一般會遇到 某種語言的數據結構或對象的傳輸。這種不能直接傳輸的數據每每須要經過 概述 開發某些分佈式系統時,經常使用的功能之一就是要在進程之間交互數據,固然,你能夠用管道,shared memory,嵌入式數據庫, in memory db等。但使用這些方式傳送數據一般會遇到 某種語言的數據結構或對象的傳輸。這種不能直接傳輸的數據每每須要經過一種「協議」進行編碼解碼,序列化就是一種方式。而序列化的方法不少,如python的pickle,json, kryo等。google的protobuf是我認爲最好的一種序列化協議之一。 本人主要使用python和c/c++, 而protobuf對這兩種語言都作了實現: python官方入門教程(英文): http://code.google.com/apis/protocolbuffers/docs/pythontutorial.html python官方API文檔 http://code.google.com/apis/protocolbuffers/docs/reference/python/index.html python如何使用: 1. 定義數據的格式(schema),創建文件addressbook.proto: package tutorial; 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 = 1; } 2. 編譯.proto文件: protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/addressbook.proto 3. 使用這種格式的數據 兩個主要的函數分別是: SerializeToString() 序列化數據對象 ParseFromString() 反序列化 編寫以下的測試用的python代碼: import addressbook_pb2 person = addressbook_pb2.Person() person.id = 1234 person.name = "John Doe" person.email = "jdoe@example.com" phone = person.phone.add() phone.number = "555-4321" phone.type = addressbook_pb2.Person.HOME print person str = person.SerializeToString() print len(str) pread = addressbook_pb2.Person() pread.ParseFromString(str) print pread #!/usr/bin/env python import addressbook_pb2 person = addressbook_pb2.Person() person.id = 1234 person.name = "John Doe" person.email = "jdoe@example.com" phone = person.phone.add() phone.number = "555-4321" phone.type = addressbook_pb2.Person.HOME print person str = person.SerializeToString() print len(str) pread = addressbook_pb2.Person() pread.ParseFromString(str) print pread