.Net 解析和序列化protocol buffers
阿新 • • 發佈:2021-07-21
protocol buffers被越來越多開發者使用,比如在grpc中用到,或者使用protobuf與遊戲進行通訊,也有遊戲使用它來儲存遊戲資料的。
為什麼我們要使用protobuf?
protocol buffers 是一種靈活,高效,自動化機制的結構資料序列化方法-可類比 XML,但是比 XML 更小、更快、更為簡單。
當然解析protobuf有幾種方式:
1、使用官方軟體工具包生成C# 檔案,按照官方教程就可以直接解析了。官方protobuf C#教程:https://developers.google.com/protocol-buffers/docs/csharptutorial
2、使用ServiceStack.ProtoBuf 擴充套件包解析,較方便快捷。
這裡主要介紹第二種方式。
我們首先要確定protobuf檔案:
syntax = "proto3"; package Test; message ProtoBufExample { uint32 item1 = 1; // 欄位 uint32 item2 = 2; // 欄位2 }
這裡是一個簡單的protobuf檔案:第一行syntax用來指定語法,比如這裡使用的就是proto3,也有使用proto2的,語法有所區別,proto3去掉了required等關鍵字。第二行的package是指包名,類似於C# namespace.
然後我們需要定義與proto檔案相同的類:
[ProtoContract]public class ProtoBufExample { /// <summary> /// 欄位1 /// </summary> [ProtoMember(1)] public uint item1 { get; set; } /// <summary> /// 欄位2 /// </summary> [ProtoMember(2)] public uint item2 { get; set; } }
類需要加上 [ProtoContract]特性,屬性需要和proto檔案中的欄位對應上。
接下來就是解析和序列化了,定義一個靜態類:
public static class ProtoBufExtensions { /// <summary> /// object To bytes /// </summary> /// <typeparam name="T"></typeparam> /// <param name="instance"></param> /// <returns></returns> public static byte[] ObjectToBytes<T>(T instance) { try { byte[] array; if (instance == null) { array = new byte[0]; } else { var memoryStream = new MemoryStream(); Serializer.Serialize(memoryStream, instance); array = new byte[memoryStream.Length]; memoryStream.Position = 0L; memoryStream.Read(array, 0, array.Length); memoryStream.Dispose(); } return array; } catch (Exception ex) { return new byte[0]; } } /// <summary> /// byte To Object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="bytesData"></param> /// <returns></returns> public static T BytesToObject<T>(byte[] bytesData) { if (bytesData.Length == 0) return default; try { var memoryStream = new MemoryStream(); memoryStream.Write(bytesData, 0, bytesData.Length); memoryStream.Position = 0L; var result = Serializer.Deserialize<T>(memoryStream); memoryStream.Dispose(); return result; } catch (Exception ex) { return default; } } }
然後就是呼叫:
// 序列化 byte[] result = ProtoBufExtensions.ObjectToBytes<ProtoBufExample>(protoBufExample); //解析 var result = ProtoBufExtensions.BytesToObject<ProtoBufExample>(byteAarry);
這樣就完成呼叫或者解析了,非常方便和快捷。
如有錯誤,歡迎指正,互相學習。謝謝!