protobuf-net-data
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文件里面了。

ProtoGen是用来根据***.proto文件生成对应的***.cs文件的,而做数据存储功能只需要用到protobuf-net.dll即可,至于使用哪个版本项目情况决定。下面的例子在Windows平台下新建一个C#的控制台工程,并引入ProtoBufNet\Full\net30\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是google开源的一个项目,用户数据序列化反序列化,google声称google的数据通信都是用该序列化方法。它比xml格式要少的多,甚至比二进制数据格式也小的多。
Protobuf格式协议和xml一样具有平台独立性,可以在不同平台间通信,通信所需资源很少,并可以扩展,可以旧的协议上添加新数据
Protobuf是在java和c++运行的,Protobuf-net当然就是Protobuf在.net环境下的移植。
请参见:https://code.google.com/p/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 Attrbuit,成员加上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.使用xml序列化1000个对象,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);
}

在这个实验中ProtoBuf比xml序列化小5倍,比二进制也近小一倍,有人说ProtoBuf比xml可以小到20倍,根据数据的复杂度这是有可能的。ProtoBuf的数据格式做为数据报文有着绝对优势,当然也有个弊端,它是2进制报文,没有xml格式这样的可读性,要想看懂报文内容只能用ProtoBuf反序列化了,不过我认识这基本上不是问题~
protobuf-net-data的更多相关文章
- google protobuf 简单实例
1.定义proto文件: User.proto package netty; option java_package="myprotobuf"; option java_outer ...
- 【MINA】用protobuf做编解码协议
SOCKET协议 支持java serial 与 AMF3的混合协议,目前没有基于xml 与 json的实现. 协议说明: * 9个字节协议头+协议体. * * 协议头1-4字节表示协议长度 =协议体 ...
- (中级篇 NettyNIO编解码开发)第八章-Google Protobuf 编解码-1
Google的Protobuf在业界非常流行,很多商业项目选择Protobuf作为编解码框架,这里一起回顾一下Protobuf 的优点.(1)在谷歌内部长期使用,产品成熟度高:(2)跨语言,支持 ...
- 序列化之protobuf与avro对比(Java)
最近在做socket通信中用到了关于序列化工具选型的问题,在调研过程中开始趋向于用protobuf,可以省去了编解码的过程.能够实现快速开发,且只需要维护一份协议文件即可. 但是调研过程中发现了pro ...
- netty和protobuf的使用
一.什么是protobuf Protobuf是google的开源项目,全称是Google Protocol Buffers,它是一个与语言无关.平台无关.可扩展的结构化数据序列化机制,类似XML,但它 ...
- Google Protobuf 使用 Java 版
一 . Protobuf 的入门 Protobuf 是一个灵活,高效,结构化的数据序列化框架, 相比于 XML 等传统的序列化工具,它更小,更快,更灵活,更简单. Protobuf 支持数据结构化一次 ...
- Swoole http server + yaf, swoole socket server + protobuf 等小结
拥抱swoole, 拥抱更好的php Swoole 是什么? Yaf 是什么? 接触swoole已经4年多了,一直没有好好静下心来学习.一直在做web端的应用,对网络协议和常驻内存型服务器一窍不通.一 ...
- Protobuf 小试牛刀
本文以PHP为例. 环境: CentOS 6.8 proto 3.8 PHP 7.1.12 PHP protobuf扩展 3.8.0 go1.12.5 linux/amd64 本文示例仓库地址: ht ...
- protobuf使用
一.protobuf环境搭建 Github 地址: https://github.com/protocolbuffers/protobuf 然后进入下载页 https://github.com/pro ...
- 《精通并发与Netty》学习笔记(05 - Google Protobuf与Netty的结合)
protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等.其特点是不限语言.不限平台.扩展性强 Netty也提供了对Protobuf的天然支持,我们今天 ...
随机推荐
- Codeforces Round #274 (Div. 2) --A Expression
主题链接:Expression Expression time limit per test 1 second memory limit per test 256 megabytes input st ...
- 【Hibernate学习】 ——ORM(三)
前面几种关系我们曾经就常常常使用,对于继承我们也并不陌生,常常接触的类与类之间的继承用extendskeyword,那么在表与表的关系中怎样表示呢?以下我们来讲继承映射. 继承有三种实现的策略,单表继 ...
- 恢复SQLServer实例连接
原文:恢复SQLServer实例连接 译自: http://www.mssqltips.com/sqlservertip/2682/recover-access-to-a-sql-server-ins ...
- ZOJ 2760 How Many Shortest Path(Dijistra + ISAP 最大流)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760 题意:给定一个带权有向图 G=(V, E)和源点 s.汇点 t ...
- 有意练习--Rails RESTful(一)
书要反复提及<哪里有天才>在说,大多数所谓的天才是通过反复刻意练习获得. 当你的练习时间达到10000几个小时后,.你将成为该领域的专家. 近期在学习rails怎样实现RESTful We ...
- windows 10 install oracle 12c error:[ INS-30131 ]
"[ INS-30131 ] the Initial Setup That Is Required to Run the Installation Program Validation Wa ...
- UVA 810 - A Dicey Problem(BFS)
UVA 810 - A Dicey Problem 题目链接 题意:一个骰子,给你顶面和前面.在一个起点,每次能移动到周围4格,为-1,或顶面和该位置数字一样,那么问题来了,骰子能不能走一圈回到原地, ...
- Android Dalvikvm 内存管理理解
网上非常多文件介绍了 jvm 内存管理的理论,但在 Dalvikvm 中,到底是怎样实现的. 这几天猛看了 Dalvikvm 的源码,说一下我的理解: 在大层面上讲跟理论一样,jvm 把内存分成了一些 ...
- 百度CSND博客在搜索栏中显示图片
原先以为百度搜索结果有图片是能够人为控制的,结果发现并非这样. 近期百度搜索结果的每一个条目左側出现了小图片,这一变化能够说是极大满足了用户的体验,不用进入站点就提前直观的推断出站点内容是否是自己要找 ...
- Java日志性能那些事(转)
在任何系统中,日志都是非常重要的组成部分,它是反映系统运行情况的重要依据,也是排查问题时的必要线索.绝大多数人都认可日志的重要性,但是又有多少人仔细想过该怎么打日志,日志对性能的影响究竟有多大呢?今天 ...