zoukankan      html  css  js  c++  java
  • .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

    如有错误,欢迎指正,互相学习。谢谢!
  • 相关阅读:
    CDH简易离线部署文档
    算法图解读书笔记
    html 知识整理
    Django admin 组件 原理分析与扩展使用 之 sites.py (一)
    阿里云 centos7 django + uWSGI+Nginx + python3 部署攻略
    git 命令和使用场景总结
    由select引发的思考
    Python 实现单例模式的一些思考
    pep 8 规范的一些记录
    python 垃圾回收机制的思考
  • 原文地址:https://www.cnblogs.com/Ivan-Wu/p/15038586.html
Copyright © 2011-2022 走看看