您的位置:首页 > 编程语言 > C#

C# protobuf的使用方法

2016-05-20 10:06 716 查看
简介

Protobuf是google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言。

支持多种编程语言,现:Java、c#、c++、go 和

Python。

基于二进制,因此比传统的XML表示高效短小得多

作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

使用

1、下载地址:http://code.google.com/p/protobuf/downloads/

2、proto文件格式

package 对应于c#中的命名空间

required 对应类的属性

optional 创建一个具有默认值的属性,通过[default=XXX]设置默认值,不添加默认为空置。如string默认为“”,int默认为0

enum 创建枚举

message 创建自定义类或内部类

repeated 对应list列表数据

proto数据类型:



示例:

<code class="hljs go has-numbering"><span class="hljs-keyword">package</span> test;
message Person {
required <span class="hljs-typename">string</span> name<span class="hljs-number">=1</span>;
required <span class="hljs-typename">int32</span> id<span class="hljs-number">=2</span>;
optional <span class="hljs-typename">string</span> email<span class="hljs-number">=3</span> ;

enum PhoneType {
MOBILE<span class="hljs-number">=0</span>;
HOME<span class="hljs-number">=1</span>;
WORK<span class="hljs-number">=2</span>;
}

message PhoneNumber {
required <span class="hljs-typename">string</span> number<span class="hljs-number">=1</span>;
optional PhoneType <span class="hljs-keyword">type</span><span class="hljs-number">=2</span> [<span class="hljs-keyword">default</span>=HOME];
}

repeated PhoneNumber phone<span class="hljs-number">=4</span>;
}</code>

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

转换之后的文件:

<code class="hljs cs has-numbering"><span class="hljs-comment">//------------------------------------------------------------------------------</span>
<span class="hljs-comment">// <auto-generated></span>
<span class="hljs-comment">//     This code was generated by a tool.</span>
<span class="hljs-comment">//</span>
<span class="hljs-comment">//     Changes to this file may cause incorrect behavior and will be lost if</span>
<span class="hljs-comment">//     the code is regenerated.</span>
<span class="hljs-comment">// </auto-generated></span>
<span class="hljs-comment">//------------------------------------------------------------------------------</span>

<span class="hljs-comment">// Generated from: input/test.proto</span>
namespace input.test
{
[global::System.Serializable, global::ProtoBuf.ProtoContract(Name=<span class="hljs-string">@"Person"</span>)]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">partial</span> <span class="hljs-keyword">class</span> Person : global::ProtoBuf.IExtensible
{
<span class="hljs-keyword">public</span> <span class="hljs-title">Person</span>() {}

<span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _name;
[global::ProtoBuf.ProtoMember(<span class="hljs-number">1</span>, IsRequired = <span class="hljs-keyword">true</span>, Name=<span class="hljs-string">@"name"</span>, DataFormat = global::ProtoBuf.DataFormat.Default)]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> name
{
<span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> _name; }
<span class="hljs-keyword">set</span> { _name = <span class="hljs-keyword">value</span>; }
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> _id;
[global::ProtoBuf.ProtoMember(<span class="hljs-number">2</span>, IsRequired = <span class="hljs-keyword">true</span>, Name=<span class="hljs-string">@"id"</span>, DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> id
{
<span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> _id; }
<span class="hljs-keyword">set</span> { _id = <span class="hljs-keyword">value</span>; }
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _email = <span class="hljs-string">""</span>;
[global::ProtoBuf.ProtoMember(<span class="hljs-number">3</span>, IsRequired = <span class="hljs-keyword">false</span>, Name=<span class="hljs-string">@"email"</span>, DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue(<span class="hljs-string">""</span>)]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> email
{
<span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> _email; }
<span class="hljs-keyword">set</span> { _email = <span class="hljs-keyword">value</span>; }
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> global::System.Collections.Generic.List<Person.PhoneNumber> _phone = <span class="hljs-keyword">new</span> global::System.Collections.Generic.List<Person.PhoneNumber>();
[global::ProtoBuf.ProtoMember(<span class="hljs-number">4</span>, Name=<span class="hljs-string">@"phone"</span>, DataFormat = global::ProtoBuf.DataFormat.Default)]
<span class="hljs-keyword">public</span> global::System.Collections.Generic.List<Person.PhoneNumber> phone
{
<span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> _phone; }
}

[global::System.Serializable, global::ProtoBuf.ProtoContract(Name=<span class="hljs-string">@"PhoneNumber"</span>)]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">partial</span> <span class="hljs-keyword">class</span> PhoneNumber : global::ProtoBuf.IExtensible
{
<span class="hljs-keyword">public</span> <span class="hljs-title">PhoneNumber</span>() {}

<span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _number;
[global::ProtoBuf.ProtoMember(<span class="hljs-number">1</span>, IsRequired = <span class="hljs-keyword">true</span>, Name=<span class="hljs-string">@"number"</span>, DataFormat = global::ProtoBuf.DataFormat.Default)]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> number
{
<span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> _number; }
<span class="hljs-keyword">set</span> { _number = <span class="hljs-keyword">value</span>; }
}
<span class="hljs-keyword">private</span> Person.PhoneType _type = Person.PhoneType.HOME;
[global::ProtoBuf.ProtoMember(<span class="hljs-number">2</span>, IsRequired = <span class="hljs-keyword">false</span>, Name=<span class="hljs-string">@"type"</span>, DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
[global::System.ComponentModel.DefaultValue(Person.PhoneType.HOME)]
<span class="hljs-keyword">public</span> Person.PhoneType type
{
<span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> _type; }
<span class="hljs-keyword">set</span> { _type = <span class="hljs-keyword">value</span>; }
}
<span class="hljs-keyword">private</span> global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(<span class="hljs-keyword">bool</span> createIfMissing)
{ <span class="hljs-keyword">return</span> global::ProtoBuf.Extensible.GetExtensionObject(<span class="hljs-keyword">ref</span> extensionObject, createIfMissing); }
}

[global::ProtoBuf.ProtoContract(Name=<span class="hljs-string">@"PhoneType"</span>)]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">enum</span> PhoneType
{

[global::ProtoBuf.ProtoEnum(Name=<span class="hljs-string">@"MOBILE"</span>, Value=<span class="hljs-number">0</span>)]
MOBILE = <span class="hljs-number">0</span>,

[global::ProtoBuf.ProtoEnum(Name=<span class="hljs-string">@"HOME"</span>, Value=<span class="hljs-number">1</span>)]
HOME = <span class="hljs-number">1</span>,

[global::ProtoBuf.ProtoEnum(Name=<span class="hljs-string">@"WORK"</span>, Value=<span class="hljs-number">2</span>)]
WORK = <span class="hljs-number">2</span>
}

<span class="hljs-keyword">private</span> global::ProtoBuf.IExtension extensionObject;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(<span class="hljs-keyword">bool</span> createIfMissing)
{ <span class="hljs-keyword">return</span> global::ProtoBuf.Extensible.GetExtensionObject(<span class="hljs-keyword">ref</span> extensionObject, createIfMissing); }
}

}</code>

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

首先,将生成的.cs文件复制到自己的项目文件中

然后添加动态链接库文件protobuf-net.dll(该文件位于下载的proto文件的protobuf-net_r668\ProtoGen目录下)

然后在程序中引用,相关程序如下:

<code class="hljs vala has-numbering"><span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">using</span> System.Collections.Generic;
<span class="hljs-keyword">using</span> System.Linq;
<span class="hljs-keyword">using</span> System.Text;
<span class="hljs-keyword">using</span> System.Threading.Tasks;
<span class="hljs-keyword">using</span> ProtoBuf;
<span class="hljs-keyword">using</span> input.test;
<span class="hljs-keyword">using</span> System.IO;
<span class="hljs-keyword">using</span> System.Runtime.Serialization.Formatters.Binary;
<span class="hljs-class"><span class="hljs-keyword">namespace</span> <span class="hljs-title">test1</span>
{</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> Main(<span class="hljs-keyword">string</span>[] args)
{
Person p = <span class="hljs-keyword">new</span> Person();
p.name = <span class="hljs-string">"zhang san"</span>;
p.email = <span class="hljs-string">"XXXXX@qq.com"</span>;
p.id = <span class="hljs-number">12</span>;
<span class="hljs-comment">//序列化操作</span>
MemoryStream ms=<span class="hljs-keyword">new</span> MemoryStream();
<span class="hljs-comment">//BinaryFormatter bm = new BinaryFormatter();</span>
<span class="hljs-comment">//bm.Serialize(ms, p);</span>
Serializer.Serialize<Person>(ms, p);
byte[] data = ms.ToArray();<span class="hljs-comment">//length=27  709</span>

<span class="hljs-comment">//反序列化操作</span>
MemoryStream ms1 = <span class="hljs-keyword">new</span> MemoryStream(data);
<span class="hljs-comment">// BinaryFormatter bm1 = new BinaryFormatter();</span>
<span class="hljs-comment">//Person p1= bm.Deserialize(ms1) as Person;</span>
Person p1 = Serializer.Deserialize<Person>(ms1);
Console.ReadKey();
}
}
}</code>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: