zoukankan      html  css  js  c++  java
  • protobuf-net

    https://www.cnblogs.com/sifenkesi/p/4045392.html

    protobuf是google的一个开源项目,可用于以下两种用途:

      (1)数据的存储(序列化和反序列化),类似于xml、json等;

      (2)制作网络通信协议。

      源代码下载地址:https://github.com/mgravell/protobuf-net

      开源项目地址如下:https://code.google.com/p/protobuf-net/,下载解压后的目录如下所示,每个文件夹的详细介绍都在最后一个txt文件里面了。

      

      ProtoGen是用来根据***.proto文件生成对应的***.cs文件的,而做数据存储功能只需要用到protobuf-net.dll即可,至于使用哪个版本项目情况决定。下面的例子在Windows平台下新建一个C#的控制台工程,并引入ProtoBufNetFull et30protobuf-net.dll,代码如下所示:

    复制代码
    namespace TestProtoBuf
    {
        [ProtoContract]
        public class Address
        {
            [ProtoMember(1)]
            public string Line1;
            [ProtoMember(2)]
            public string Line2;
        }
    
        [ProtoContract]
        public class Person
        {
            [ProtoMember(1)]
            public int Id;
            [ProtoMember(2)]
            public string Name;
            [ProtoMember(3)]
            public Address Addr;
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Person person = new Person();
                person.Id = 1;
                person.Name = "First";
                person.Addr = new Address { Line1="line1", Line2="line2"};
    
                // ProtoBuf序列化
                using(var file = System.IO.File.Create("Person.bin"))
                {
                    ProtoBuf.Serializer.Serialize(file, person);
                }
    
                // ProtoBuf反序列化
                Person binPerson = null;
                using(var file = System.IO.File.OpenRead("Person.bin"))
                {
                    binPerson = ProtoBuf.Serializer.Deserialize<Person>(file);
                }
    
                System.Console.WriteLine(binPerson.Name);
            }
        }
    }
    复制代码

      可以看到序列化和反序列化的代码非常简单。

      protobuf提供了一种proto脚本用来编写***.proto文件,这种脚本格式简单、可读性强、方便扩展,用proto脚本定义网络协议是非常好用的。

      下面是一个proto脚本的简单例子:

    复制代码
    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;
    }
    复制代码

      requied是必须有的字段、optional是可有可无的字段、repeated是可以重复的字段(数组或列表),同时枚举字段都必须给出默认值。

      接下来就可以使用ProgoGen来根据proto脚本生成源代码cs文件了,命令行如下:

      protogen -i:test.proto -0:test.cs -ns:MyProtoBuf

      -i指定了输入,-o指定了输出,-ns指定了生成代码的namespace,上面的proto脚本生成的源码如下:

    复制代码
    //------------------------------------------------------------------------------
    // <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: file/pb.proto
    namespace MyProtoBuf
    {
      [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); }
      }
      
    }
    复制代码
  • 相关阅读:
    Unity Glossary
    Event-Driven Programming: Introduction, Tutorial, History (Stephen Ferg 著)
    2019年11月
    2019年10月
    2019年9月
    LuaFramework 学习
    xLua 学习
    2019年8月
    【原】AFNetworking源码阅读(二)
    【原】AFNetworking源码阅读(一)
  • 原文地址:https://www.cnblogs.com/alps/p/7932276.html
Copyright © 2011-2022 走看看