Protobuf的用法
1 使用Protobuf定义的特性将cs中的类标记使其可以进行二进制的序列化
a ==用Protobuf的特性来标记cs的类==
[ProtoContract]
public class LoginInfo
{
[ProtoMember(1)]
public string userName
{
get;
set;
}
[ProtoMember(2)]
public string password
{
get;
set;
}
}
b ==将标记的类序列化到文本中保存==
char[] chars = { 'a','b','c','d','e','f','g','1','2','3','4','5','6','7','A','B','D'};
List<LoginInfo> list = new List<LoginInfo>();
for (int i = 0; i < 10; i++)
{
StringBuilder stringBuilder = new StringBuilder();
Random random = new Random();
for (int j = 0; j < 8; j++)
{
int index = random.Next(0,14);
Console.WriteLine(j+"---"+index);
stringBuilder.Append(chars[index]);
}
Console.WriteLine(stringBuilder);
LoginInfo info = new LoginInfo { userName = "damon"+i,password = stringBuilder.ToString()};
list.Add(info);
}
string path = @"D:\Damon\Year_2019\Private\Project_C#\服务器\Protobuf_demo01\bin\Debug\test.bat";
using (FileStream fileStream = File.Create(path))
{
Serializer.Serialize<List<LoginInfo>>(fileStream, list);
}
c ==将序列化的数据反序列化==
using (FileStream stream = File.Open(path,FileMode.Open))
{
List<LoginInfo> infos = Serializer.Deserialize<List<LoginInfo>>(stream);
for (int i = 0; i < infos.Count; i++)
{
Console.WriteLine(infos[i].userName+"--"+infos[i].password);
}
}
2 使用Protobuf的语法格式构造Protobuf数据
a 修饰项的关键字
required 必有属性
optional 可有属性
repeated 数组
b 设定命名空间
1 以protobuf的文件名作为命名空间,message 后定义cs中的类名
c 对应的数据类型
.proto数据类型 | c#类型 |
---|---|
double | double |
float | float |
int32 | int32 |
int64 | int64 |
uint32 | uint32 |
uint64 | uint64 |
sint32 | — |
sint64 | — |
fixed32 | — |
fixed64 | — |
sfixed32 | — |
sfixed64 | — |
bool | bool |
string | string |
bytes | — |
d 枚举类型
枚举常量最好控制在uint32的整型数字范围内,枚举使用可变的编码方式,对复数支持的不够高效
建议使用正整数
message LoginReq
{
enum CommandType
{
Login=0;
Register=1;
CreateRole=2;
}
required CommandType type=1;
}
e 注释写法
使用//作为注释
message LoginReq
{
enum CommandType
{
Login=0;
Register=1;
CreateRole=2;//这里需要使用;
}
required CommandType type=1;
}
f 序列化和反序列化
使用静态泛型方法将指定的实例对象序列化成Stream流
//将一个类用Protobuf的特性进行标注
[ProtoContract]
public class LoginInfo
{
[ProtoMember(1)]
public string userName
{
get;
set;
}
[ProtoMember(2)]
public string password
{
get;
set;
}
}
//实例化被protobuf标注特性的类
LoginInfo login01 = new LoginInfo();
login01.userName = "程文浩";
login01.password = "222222";
//将序列化的结果存放在内存流中
byte[] bytes01 = null;
using (MemoryStream stream = new MemoryStream())
{
Serializer.Serialize<LoginInfo>(stream,login01);
bytes01 = stream.ToArray();
}
反序列化
反序列化和序列化成对相反出现,需要将一个流传入stream中
using (MemoryStream stream = new MemoryStream(bytes01))
{
LoginInfo info = Serializer.Deserialize<LoginInfo>(stream);
Console.WriteLine(info.userName + "--" + info.password);
}