C#使用protobuf

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数据类型: 
 
示例:

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

转换之后的文件:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// Generated from: input/test.proto
namespace input.test
{
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"Person")]
  public partial class Person : global::ProtoBuf.IExtensible
  {
    public Person() {}

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

  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"PhoneNumber")]
  public partial class PhoneNumber : global::ProtoBuf.IExtensible
  {
    public PhoneNumber() {}

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

    [global::ProtoBuf.ProtoContract(Name=@"PhoneType")]
    public enum PhoneType
    {

      [global::ProtoBuf.ProtoEnum(Name=@"MOBILE", Value=0)]
      MOBILE = 0,

      [global::ProtoBuf.ProtoEnum(Name=@"HOME", Value=1)]
      HOME = 1,

      [global::ProtoBuf.ProtoEnum(Name=@"WORK", Value=2)]
      WORK = 2
    }

    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91

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

首先,将生成的.cs文件复制到自己的项目文件中 
然后添加动态链接库文件protobuf-net.dll(该文件位于下载的proto文件的protobuf-net_r668\ProtoGen目录下) 
然后在程序中引用,相关程序如下:

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 = "[email protected]";
            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();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
时间: 2024-10-03 00:41:19

C#使用protobuf的相关文章

python通过protobuf实现rpc

由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行google,这里只是做个简单的介绍.rpc的主要功能是让分布式系统的实现更为简单,为提供强大的远程调用而不损失本地调用语义的简洁性.为了实现这个目标,rpc框架需要提供一种透明调用机制让使用者不必显示区分本地调用还是远程调用.rpc架构涉及的组件如下: 客户方像调用本地方法一样去调用远程接口方法,R

Centos6.4下安装protobuf及简单使用

1.protobuf是google公司提出的数据存储格式,详细介绍可以参考:https://code.google.com/p/protobuf/ 2.下载最新的protobuf,下载地址:https://code.google.com/p/protobuf/downloads/list 3.下载protobuf2.5.o版本,protobuf-2.5.0.tar.gz解压并进行安装. 解压:tar xvf protobuf-2.5.0.tar.gz 安装步骤:(1)./configure (2

基于protobuf的RPC实现

可以对照使用google protobuf RPC实现echo service一文看,细节本文不再描述. google protobuf只负责消息的打包和解包,并不包含RPC的实现,但其包含了RPC的定义.假设有下面的RPC定义: service MyService { rpc Echo(EchoReqMsg) returns(EchoRespMsg) } 那么要实现这个RPC需要最少做哪些事?总结起来需要完成以下几步: 客户端 RPC客户端需要实现google::protobuf::RpcCh

Windows下编译protobuf v3.3.0

一:概述 关于 protobuf 在此不再多说,此处记录下成功编译步骤以备日后查阅.注意:本文并不是使用cmake gui进行编译的,如果熟悉cmake gui的话,也可以使用gui进行生成编译. 二:准备资源及工具 VS2013或以上版本,安装好 protobuf 源码,下载地址:官网:http://code.google.com/p/protobuf/git网:https://github.com/google/protobuf或git:https://github.com/google/p

Skynet服务器框架(五) 使用pbc(protobuf)

引言: 假如我们要建立的skynet服务器与客户端的连接方式为长连接,且选择了Google的Protobuf来定制我们的网络协议,那么,接下来我们要解决的问题就是:如何在skynet框架中使用socket+protobuf. API 几个常用的skynet接口: * 输出错误信息: skynet.error(...) * 获取本地服务句柄方式: skynet.localname(...) * 设置定时器方式: skynet.timeout(...) * skynet强制退出方式: skyname

uLua/toLua加载protobuf转lua的table为bool的解决方法

当我们加载protobuf对应的lua的table的时候,我们使用如下方式来加载 local person_pb = require 'Protol.person_pb' 注意,这个table前面的Protol.这段一定不能去掉,如果去掉了,你加载到的persob_pb将会是一个bool类型的值. 如果加上这个Protol.的话,你才能加载到真正有的数据表. 也许是lua和protobuf工具关联时的一个约定,也许是这样,反正要放在protol文件夹下就能加载到数据表.

序列化之protobuf与avro对比(Java)

最近在做socket通信中用到了关于序列化工具选型的问题,在调研过程中开始趋向于用protobuf,可以省去了编解码的过程.能够实现快速开发,且只需要维护一份协议文件即可. 但是调研过程中发现了protobuf的一些弊端,比如需要生成相应的文件类,和业务绑定太紧密,所以在看了AVRO之后发现它完美解决了这个问题. 下面记录下对这两种序列化工具的入门与测评. 一.protobuf基本操作 protobuf简介: Protocol Buffers (a.k.a., protobuf) are Goo

Golang版protobuf编译

官方网址: https://developers.google.com/protocol-buffers/ (需要FQ) 代码仓库: https://github.com/google/protobuf  (C++) https://github.com/golang/protobuf  (Golang) https://developers.google.com/protocol-buffers/docs/gotutorial (英文版教程) 本文以下部分按照英文版教程操作(windows  

[z]protobuf实现c++与java之间的数据传递,beancopy数据到前台

[z]http://blog.csdn.net/xhyzdai/article/details/46684335 定义proto文件 [plain] view plain copy option java_package = "com.wy.web"; message my_message{ required string startedTime =1; required string version=2; required double configuredCapacity=3; r

protobuf 学习 收藏的文章

Protobuf数据格式解析: packed repeated与repeated的区别在于编码方式不一样,repeated将多个属性类型与值分开存储.而packed repeated采用Length-delimited方式. proto3的repeated默认就是使用packed这种方式来存储,(proto2与proto3区别在于.proto的语法). http://blog.csdn.net/zhaozheng7758/article/details/6749000: [packed =fal