protobuf-net-data

14674 단어 protobuf
protobuf-net
http://www.codeproject.com/Articles/642677/Protobuf-net-the-unofficial-manual
https://github.com/rdingwall/protobuf-net-data
https://github.com/mgravell/protobuf-net
protobuf 는 google 의 오픈 소스 프로젝트 로 다음 과 같은 두 가지 용도 로 사용 할 수 있 습 니 다.
(1) 데이터 의 저장 (직렬 화 와 반 직렬 화) 은 xml, json 등 과 유사 하 다.
(2) 인터넷 통신 프로 토 콜 제작.
소스 코드 다운로드 주소:https://github.com/mgravell/protobuf-net
오픈 소스 항목 주 소 는 다음 과 같 습 니 다.https://code.google.com/p/protobuf-net/압축 해 제 된 디 렉 터 리 는 다음 과 같 습 니 다. 모든 폴 더 의 상세 한 소 개 는 마지막 txt 파일 에 있 습 니 다.
   protobuf-net-data_第1张图片
ProtoGen 은 * *. proto 파일 에 따라 대응 하 는 * *. cs 파일 을 생 성 하 는 데 사 용 됩 니 다. 데이터 저장 기능 을 하려 면 protobuf - net. dll 만 사용 하면 됩 니 다. 어떤 버 전 항목 을 사용 할 지 결정 합 니 다.다음 예 는 Windows 플랫폼 에서 C\# 콘 솔 프로젝트 를 새로 만 들 고 ProtoBufNet\Fullet 30\\protobuf - 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); }
  }
  
}


  to be continue...
 
ProtoBuf - net 이 뭐야?
Protobuf 는 구 글 이 소스 를 시작 하 는 프로젝트 로 사용자 데이터 의 직렬 화 반 직렬 화, 구 글 은 구 글 의 데이터 통신 이 모두 이 직렬 화 방법 을 사용한다 고 주장 합 니 다.xml 형식 보다 훨씬 적 고 바 이 너 리 데이터 형식 보다 도 작 습 니 다.
Protobuf 형식 프로 토 콜 은 xml 와 마찬가지 로 플랫폼 독립 성 을 가지 고 서로 다른 플랫폼 에서 통신 할 수 있 으 며 통신 에 필요 한 자원 이 적 고 확장 할 수 있 으 며 오래된 프로 토 콜 에 새로운 데 이 터 를 추가 할 수 있 습 니 다.
Protobuf 는 자바 와 c++ 에서 실 행 됩 니 다. Protobuf - net 은 당연히 Protobuf 가. net 환경 에서 이식 한 것 입 니 다.
참조 하 십시오. 
Get Start
[ProtoBuf.ProtoContract]
    public class Person
    {
        [ProtoBuf.ProtoMember(1)]
        public int Id { get; set; }
        [ProtoBuf.ProtoMember(2)]
        public string Name { get; set; }
        [ProtoBuf.ProtoMember(3)]
        public Address Address { get; set; }
    }

    [ProtoBuf.ProtoContract]
    public class Address
    {
        [ProtoBuf.ProtoMember(1)]
        public string Line1 { get; set; }
        [ProtoBuf.ProtoMember(2)]
        public string Line2 { get; set; }
    }

클래스 앞 에 ProtoContract Attbuit 를 추가 하고 구성원 에 ProtoMember Attribute 를 추가 하면 됩 니 다. 그 중에서 ProtoMember 는 0 이상 의 int 유형의 값 이 필요 합 니 다. 원칙적으로 이 int 유형 은 크기 제한 이 없 지만 1 부터 시작 하 는 것 이 좋 은 습관 입 니 다. 또한 이 매개 변 수 는 이러한 구성원 의 유일한 표지 이 어야 합 니 다. 중복 할 수 없습니다.
서열 화
            var person = new Person
            {
                Id = 1,
                Name = "First",
                Address = new Address { Line1 = "Line1", Line2 = "Line2" }
            };
            using (var file = System.IO.File.Create("Person.bin"))
            {
                ProtoBuf.Serializer.Serialize(file, person);
            }

 
역 직렬 화
Person newPerson;
using (var file = System.IO.File.OpenRead("Person.bin"))
{
    newPerson = ProtoBuf.Serializer.Deserialize<Person>(file);
}
使用起来很简单,代码移植也会相当方便,下面我要对比下序列化的文件大小。
1.使用ProtoBuf序列化1000个对象,查看Person.bin文件大小为:30 KB (29,760 字节)
List<Person> list = new List<Person>();
            for (var i = 0; i < 1000; i++)
            {
                var person = new Person
                {
                    Id = i,
                    Name = "Name"+i,
                    Address = new Address { Line1 = "Line1", Line2 = "Line2" }
                };
                list.Add(person);
            }

            using (var file = System.IO.File.Create("Person.bin"))
            {
                ProtoBuf.Serializer.Serialize(file, list);
            }

2. 1000 개의 대상 을 xml 로 정렬 하고 Person. xml 크기 는 152 KB (155, 935 바이트) 입 니 다.
            List<Person> list = new List<Person>();
            for (var i = 0; i < 1000; i++)
            {
                var person = new Person
                {
                    Id = i,
                    Name = "Name"+i,
                    Address = new Address { Line1 = "Line1", Line2 = "Line2" }
                };
                list.Add(person);
            }

            System.Xml.Serialization.XmlSerializer xmlSerizlizer = new System.Xml.Serialization.XmlSerializer(typeof(List<Person>));
            using(var file= System.IO.File.Create("Persion.xml")){
                xmlSerizlizer.Serialize(file, list);
            }

3. binary 를 사용 하여 1000 개의 대상 을 정렬 합 니 다. Person. dat 크기 는 54.1 KB (55, 445 바이트) 입 니 다.
            List<Person> list = new List<Person>();
            for (var i = 0; i < 1000; i++)
            {
                var person = new Person
                {
                    Id = i,
                    Name = "Name"+i,
                    Address = new Address { Line1 = "Line1", Line2 = "Line2" }
                };
                list.Add(person);
            }
            
            using(var file = new System.IO.FileStream("Person.dat", System.IO.FileMode.Create))
            {
                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter =
                    new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                binaryFormatter.Serialize(file, list);
            }

https://code.google.com/p/protobuf-net/
이 실험 에서 ProtoBuf 는 xml 직렬 화 보다 5 배 작고 이 진 보다 도 배 가까이 작 으 며, 어떤 사람 은 ProtoBuf 가 xml 보다 20 배 까지 작 을 수 있다 고 말 하 는데, 데이터 의 복잡 도 에 따라 가능 하 다.ProtoBuf 의 데이터 형식 은 데이터 메시지 로 서 절대적 인 장점 을 가지 고 있 습 니 다. 물론 단점 도 있 습 니 다. 2 진 메시지 입 니 다. xml 형식 과 같은 가 독성 이 없습니다. 메시지 내용 을 알 아 보 려 면 ProtoBuf 로 역 직렬 화 할 수 밖 에 없습니다. 하지만 저 는 이것 이 기본적으로 문제 가 아니 라 는 것 을 알 고 있 습 니 다.
분류: 
image

좋은 웹페이지 즐겨찾기