8 24 81

.Net 解析和序列化Protocol Buffers

      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 扩展包解析,较方便快捷。

 


 

第一种方式:

通过nuget包下载 Google.Protobuf.Tools这个包,里面有proto.exe 工具,按照官方文档命令就可以输出cs文件:

 

protoc.exe --proto_path=. --csharp_out=. main.proto        // 输出到当前目录

 

这里的main.proto就是需要转换的proto文件

 


 

第二种方式:

我们首先要确定protobuf文件:

 

syntax = "proto3";
package Test;
message ProtoBufExample
{
    uint32 item1 = 1; // 字段
    uint32 item2 = 2; // 字段2
}

 

这里是一个简单的protobuf文件:第一行syntax用来指定语法,比如这里使用的就是proto3,也有使用proto2的,语法有所区别,proto3去掉了required等关键字。第二行的package是指包名,类似于C# namespace.

proto2官方说明: https://developers.google.com/protocol-buffers/docs/proto

proto3官方说明:https://developers.google.com/protocol-buffers/docs/proto3

然后我们需要定义与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);

这样就完成调用或者解析了,非常方便和快捷。

 附上链接:

ServiceStack.ProtoBuf github地址 :https://github.com/ServiceStack/ServiceStack

官方开发者文档:https://developers.google.com/protocol-buffers/docs/overview

posted @   Ivan_Ivan  阅读(243)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示