C# protobuf的使用方法

简介
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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值