ProtoBuf

這一篇應該是我ProtoBuf的系列文章第二篇,上一篇只簡單說了一些安裝方式與一些定義檔
的設定根本就不知道該如何使用這一個好用的序列化工具。依樣會是使用protobuf-net
這一個套件來做一個簡單的紀錄。

ProtoBuf 序列化

在使用 ProtoBuf 的第一步就必須了解 Stream 的資料格式,因為在(反)序列化
的過程中,預設都是使用 Stream 作為媒介。序列化的部份是使用 Serializer.Serialize
這個方法來處理。

Simple Code 1 - 序列化

1
2
3
4
5
6
7
8
9
10
11
12
public void SerializeToStream<T>(T data, Stream stream)
{
Serializer.Serialize(stream, data)
}
public void Main()
{
using (var stream = new MemoryStream())
{
this.SerializeToStream<object>(data, stream);
}
}

主要原因是若Stream關閉後就無法做任何的操作,所以交由外部來控制Stream的資源初始與回收。
可以在序列化成為 Array 或 String 的格式。

Simple Code 2 - Serialize to byte array and string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public byte[] SerializeToBytes<T>(T data)
{
byte[] result;
using (var stream = new MemoryStream())
{
this.SerializeToStream(data, stream);
result = stream.ToArray();
}
return result;
}
public string SerializeToString<T>(T data)
{
string result;
using (var stream = new MemoryStream())
{
this.SerializeToStream(data, stream);
result = Encoding.ASCII.GetString(stream.ToArray());
}
return result;
}

在Format 成 String 我是採用ASCII的編碼方式,讓他出來會像16進位的感覺。

也可以使用 Convert.ToBase64String(stream.ToArray()); 產生文字資料

ProtoBuf 反序列化

在反序列化的部分也是預設採用 Stream 的資料格式來處理,

Simple Code 3 - 反序列化

1
2
3
4
public T SerializeToStream<T>(Stream stream)
{
return Serializer.Deserialize<T>(stream, data)
}

Simple Code 4 - 針對 Byte array and string deserialize

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public T DeSerializeFromBytes<T>(byte[] data)
{
T result;
using (var stream = new MemoryStream(data))
{
stream.Seek(0, SeekOrigin.Begin);
result = this.DeSerializeFromStream<T>(stream);
}
return result;
}
public T DeSerializeFromString<T>(string data)
{
return this.DeSerializeFromBytes<T>(Encoding.ASCII.GetBytes(data));
}

注: 若string是使用base64字元輸出,那麼在deserialize時就必須使用
Convert.FromBase64String(data) 處理