关于protobuf (protobuf-net版)

    xiaoxiao2023-10-28  170

    protobuf 简介

    Protobuf是google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言。 支持多种编程语言,现:Java、c#、c++、Go 和 Python。 基于二进制,因此比传统的XML表示高效短小得多 。

    protobuf 应用场景

    作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。 个人认为,主要用于数据交互和共享,此种情况需要双方制定一个特定的数据结构,那么使用ProtoBuf定义一个数据结构,然后大家从这个描述文件,各自生成自己使用的编程语言对应的代码文件,再使用这些代码对双方的数据进行处理。那么,只要都遵守这个数据文件格式,数据共享就可以实现夸平台。如果数据描述文件做了修改,只要遵守一定的规则,那么原有数据还是可以兼容使用的。这个就是做了一个平台无关的文件与平台和语言相关的数据对象之间的适配转化工作,就和很多xml解析器一样。

    protobuf-net版

    源代码下载地址:https://github.com/mgravell/protobuf-net 开源项目地址如下:https://code.google.com/p/protobuf-net/

    proto文件格式

    package对应于c#中的命名空间 required对应类的属性 optional创建一个具有默认值的属性,通过 [default=XXX]设置默认值,不添加默认为空置。如string默认为“”,int默认为0 enum创建枚举 message创建自定义类或内部类 repeated对应list列表数据

    proto数据类型

    .proto类型Java 类型C++类型备注doubledoubledoublefloatfloatfloatint32intint32使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint32。int64longint64使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint64。uint32int[1]uint32Uses variable-length encoding.uint64long[1]uint64Uses variable-length encoding.sint32intint32使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。sint64longint64使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。fixed32int[1]uint32总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。fixed64long[1]uint64总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。sfixed32intint32总是4个字节。sfixed64longint64总是8个字节。boolbooleanboolstringStringstring一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。bytesByteStringstring可能包含任意顺序的字节数据。

    示例

    package test; 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; }

    通过.proto文件导出C#支持的.cs类文件

    下载导出工具 ProtoGen.exe 下载地址: http://pan.baidu.com/s/1eRIv3oe

    把要转的.proto文件放到该目录中

    通过cmd命令行进入到该目录 使用如下命令行导出.cs文件

    protogen.exe -i:Person.proto -o:Person.cs

    命令解释 protogen -i:test.proto -o:test.cs -ns:UGE.Metadata -p:import=UGE 这句话的意思是, 输入test.proto文件, 给我生成 test.cs 文件, 代码在 namespace UGE.Metadata里, 顺便引用下 using UGE.

    proto文件编辑的命令

    protogen -i:input.proto -o:output.cs protogen -i:input.proto -o:output.xml -t:xml protogen -i:input.proto -o:output.cs -p:datacontract -q protogen -i:input.proto -o:output.cs -p:observable=true

    proto转化后的.cs文件的序列化和反序列化

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ProtoBuf; using input.test; using System.IO; using System.Runtime.Serialization.Formatters.Binary; namespace test1 { class Program { static void Main(string[] args) { Person p = new Person(); p.name = "zhang san"; p.email = "XXXXX@qq.com"; p.id = 12; //序列化操作 MemoryStream ms=new MemoryStream(); //BinaryFormatter bm = new BinaryFormatter(); //bm.Serialize(ms, p); Serializer.Serialize<Person>(ms, p); byte[] data = ms.ToArray();//length=27 709 //反序列化操作 MemoryStream ms1 = new MemoryStream(data); // BinaryFormatter bm1 = new BinaryFormatter(); //Person p1= bm.Deserialize(ms1) as Person; Person p1 = Serializer.Deserialize<Person>(ms1); Console.ReadKey(); } } }

    遇到的问题

    如果生成的时候提示找不到google/protobuf/descriptor.proto 要下载protobuf-csharp-port-master https://code.google.com/archive/p/protobuf-net/downloads 并把google目录放到你自己的.proto文件的同级目录中

    最新回复(0)