协议缓冲区(又叫,protobuf)是谷歌的可扩展的结构化数据序列化机制。它支持多种语言、多种平台。https://github.com/google/protobuf
什么是协议缓冲区?
协议缓冲区是谷歌的语言中立的,平台中立的,可扩展的机制,用于序列化结构化数据 - 认为XML,但更小,更快,更简单。 您可以定义您希望将数据结构化为一次,然后可以使用特殊的生成源代码轻松地将结构化数据写入和读取各种数据流并使用各种语言。
选择你最喜欢的语言
协议缓冲区目前支持Java,Python,Objective-C和C ++中生成的代码。 使用我们新的proto3语言版本,您还可以使用更多语言的Go,JavaNano,Ruby和C#。
我如何开始?
1、下载并安装协议缓冲区编译器:https://github.com/google/protobuf
2、阅读概述:https://developers.google.com/protocol-buffers/docs/overview
3、练习使用您选择的语言的教程:https://developers.google.com/protocol-buffers/docs/tutorials
C#使用方法
1、使用NuGet安装`Google.Protobuf`和`Google.Protobuf.Tools`。
2、创建`addressbook.proto`文件,文件内容如下:
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
option csharp_namespace = "learn_protobuf.AddressBook";
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
google.protobuf.Timestamp last_updated = 5;
}
message AddressBook {
repeated Person people = 1;
}
3、使用工具 packages/Google.Protobuf.Tools.3.4.0/tools/windows_x64/protoc.exe 编译 addressbook.proto,注意要把 packages/Google.Protobuf.Tools.3.4.0/tools/google 文件夹跟 exe 放到同一个目录,否则找不到 google/protobuf/timestamp.proto 包。然后,把 addressbook.proto 也放到同一个目录。打开 cmd 执行以下命令。
protoc -I=. --csharp_out=. ./addressbook.proto
会自动生成 Addressbook.cs,这时就可以用这个类进行序列化和反序列化了。
4、引入命名空间。
using Google.Protobuf;
using learn_protobuf.AddressBook;
5、序列化。
// 要序列化的数据
Person john = new Person
{
Id = 1234,
Name = "John Doe",
Email = "jdoe@example.com",
Phones =
{
new Person.Types.PhoneNumber { Number = "555-4321", Type = Person.Types.PhoneType.Home } }
};
// 将序列化的数据写入文件。
using (var output = File.Create("john.dat"))
{
john.WriteTo(output);
}
}
6、反序列化。
// 读取序列化的数据。
var john = new Person();
using (var input = File.OpenRead("john.dat"))
{
john = Person.Parser.ParseFrom(input);
}
js使用方法
1、使用上面提到的 addressbook.proto 和 protoc.exe 工具生成 addressbook_libs.js。命令:
protoc --js_out=library=addressbook_libs,binary:. google/protobuf/timestamp.proto addressbook.proto
2、html页面需要引入谷歌闭包工具包 goog 中的一些类和 protobuf/js 中的一些类,具体请参照源码。
<script src="js/goog/base.js"></script>
<script src="js/binary/constants.js"></script>
<script src="js/binary/utils.js"></script>
<script src="js/binary/arith.js"></script>
<script src="js/binary/encoder.js"></script>
<script src="js/binary/decoder.js"></script>
<script src="js/binary/reader.js"></script>
<script src="js/binary/writer.js"></script>
<script src="js/map.js"></script>
<script src="js/message.js"></script>
<script src="js/addressbook_libs.js"></script>
3、js类转二进制数据方法。
goog.require('proto.tutorial.AddressBook');
goog.require('proto.tutorial.Person');
goog.require('proto.tutorial.Person.PhoneNumber');
goog.require('proto.tutorial.Person.PhoneType');
var person = new proto.tutorial.Person();
person.setId(1234);
person.setName('John Doe');
person.setEmail('jdoe@example.com');
var phone = new proto.tutorial.Person.PhoneNumber();
phone.setNumber('555-4321');
phone.setType(proto.tutorial.Person.PhoneType.Home);
person.addPhones(phone);
var bytes = person.serializeBinary();
4、二进制转js类方法。
var person2 = proto.tutorial.Person.deserializeBinary(bytes);
console.log('Id:' + person2.getId());
console.log('Name:' + person2.getName());
console.log('Email:' + person2.getEmail());
person2.getPhonesList().forEach((n, i) => {
console.log('phoneNumber:' + n.getNumber());
console.log('phoneType:' + n.getType());
});
优势
跟使用 json 或 xml 来保存数据比较,使用 protobuf 生成的文件要小得多,适合网络进行大数据量的传输。