公司要想做个网站这么弄网页制作教材
更新日期:2025年9月8日。
Github 仓库:https://github.com/SaiTingHu/ProtobufNet
索引
- 一、Protobuf简介
- 二、使用Protobuf
- 1.获取protobuf-net的DLL
- 2.标记数据结构
- 3.序列化数据
- 4.反序列化数据
- 5.protobuf-net性能测试
一、Protobuf简介
Protobuf
(Protocol Buffers)是Google开发的一种轻量级、高效的结构化数据序列化格式,用于数据存储、传输和通信。它是一种语言无关、平台无关的数据描述语言,通过定义数据结构和类型,可生成对应编程语言的代码,实现数据的序列化与反序列化。
Protobuf的核心特点包括:
- 高效性:相比XML、JSON等格式,Protobuf序列化后的数据体积更小,解析速度更快,适合性能敏感场景。
- 结构化定义:通过.proto文件描述数据结构(如字段类型、编号等),编译后可生成多语言代码(如Java、Python、C++等),确保跨平台兼容性。
- 灵活性:支持数据模式的扩展,新增字段不会破坏已有代码的兼容性。
二、使用Protobuf
在Unity中推荐使用Protobuf的.Net
实现:protobuf-net。
1.获取protobuf-net的DLL
由于protobuf-net
为基于Visual Studio的项目,所以我们可以通过在Visual Studio中以NuGet
包的形式获取protobuf-net
的DLL。
不过此过程我们可以跳过,因为在文章开头的源码链接里(ProtobufNet
模块)已包含了protobuf-net
所需的所有DLL。
2.标记数据结构
且由于protobuf-net
的特性,我们在使用时不用定义.proto文件等这些繁琐的流程,只需在需要序列化的数据结构类中做出标记即可。
比如如下一个玩家信息类:
[ProtoContract]
public class PlayerInfo
{/// <summary>/// 玩家ID/// </summary>[ProtoMember(1)]public long ID;/// <summary>/// 玩家姓名/// </summary>[ProtoMember(2)]public string Name;/// <summary>/// 玩家年龄/// </summary>[ProtoMember(3)]public int Age;/// <summary>/// 玩家性别/// </summary>[ProtoMember(4)]public string Sex;
}
使用
[ProtoContract]
标记序列化类;
使用[ProtoMember(序号)]
标记序列化成员;
注意:由于protobuf-net
会使用 ProtoMember 指定的序号
来序列化、反序列化数据(省去了在数据中包含成员名称所占用的空间),所以在单个类中序号
不能重复,且后续修改成员的名称也不会影响之前已序列化的数据。
3.序列化数据
完成数据结构的标记后,序列化数据的方式将非常简单:
PlayerInfo playerInfo = new PlayerInfo() {ID = 0,Name = "张三",Age = 25,Sex = "男"};//将playerInfo对象序列化为字节数组byte[] datas = ProtoBufToolkit.Serialize(playerInfo);
4.反序列化数据
反序列化数据的方式也非常简单:
PlayerInfo playerInfo = new PlayerInfo();byte[] datas = GetPlayerDatas();//将字节数组反序列化到已有对象playerInfo,省去重复创建对象的开销,降低GC压力ProtoBufToolkit.Deserialize(datas, playerInfo);
5.protobuf-net性能测试
在此我们做一个小小的性能测试,用于对比protobuf-net
和Json
在序列化性能上的差异:
PlayerInfo playerInfo = new PlayerInfo() {ID = 0,Name = "张三",Age = 25,Sex = "男"};byte[] datas = ProtoBufToolkit.Serialize(playerInfo);Log.Info($"使用protobuf-net序列化数据,序列化后大小:{datas.Length} 字节。");string json = JsonToolkit.JsonToString(playerInfo);datas = Encoding.Default.GetBytes(json);Log.Info($"使用Json序列化数据,序列化后大小:{datas.Length} 字节。");
可以看到,protobuf-net
序列化后的数据比Json
小了数倍,这在一些高频数据交互的网络场景能够节省大量带宽,并显著降低延迟。
所以Protobuf
是网络通信、数据存储、跨平台数据交换等场景的首选。