当前位置: 首页 > news >正文

Protobuf协议生成和使用

知识点一 利用protoc.exe编译器生成脚本文件

          //1.打开cmd窗口
          //2.进入protoc.exe所在文件夹(也可以直接将exe文件拖入cmd窗口中)
          //3.输入转换指令
          //protoc.exe -I=配置路径 --csharp_out=输出路径 配置文件名

         //注意:路径不要有中文和特殊符号,避免生成失败

知识点二 测试生成对象是否能使用

TestMsg msg = new TestMsg();msg.TestBool = true;//对应的和List以及Dictionary使用方式一样的 数组和字典对象msg.ListInt.Add(1);print(msg.ListInt[0]);msg.TestMap.Add(1, "DamnF");print(msg.TestMap[1]);//枚举msg.TestEnum = TestEnum.Boss;msg.TestEnum2 = TestMsg.Types.TestEnum2.Boss;//内部枚举msg.TestMsg2 = new TestMsg2();msg.TestMsg2.TestInt32 = 99;//其他内部类对象msg.TestMsg3 = new TestMsg.Types.TestMsg3();msg.TestMsg3.TestInt32 = 55;//在另一个生成的脚本当中的类 如果命名空间不同 需要命名空间点出来使用msg.TestHeart = new GameSystemTest.HeartMsg();

制作ProtobufTool协议生成工具

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEngine;public class ProtobufTool
{//协议配置文件所在路径private static string PROTO_PATH = "C:\\Users\\HONOR\\Desktop\\TeachNet\\Protobuf\\proto";//协议生成可执行文件的路径private static string PROTOC_PATH = "C:\\Users\\HONOR\\Desktop\\TeachNet\\Protobuf\\protoc.exe";//C#文件的生成路径private static string CSHARP_PATH = "C:\\Users\\HONOR\\Desktop\\TeachNet\\Protobuf\\csharp";//C++文件的生成路径private static string CPP_PATH = "C:\\Users\\HONOR\\Desktop\\TeachNet\\Protobuf\\cpp";//Java文件的生成路径private static string JAVA_PATH = "C:\\Users\\HONOR\\Desktop\\TeachNet\\Protobuf\\java";[MenuItem("ProtobufTool/生成C#代码")]private static void GenerateCSharp(){Generate("csharp_out",CSHARP_PATH);}[MenuItem("ProtobufTool/生成C++代码")]private static void GenerateCpp(){Generate("cpp_out",CPP_PATH);}[MenuItem("ProtobufTool/生成Java代码")]private static void GenerateJava(){Generate("java_out", JAVA_PATH);}private static void Generate(string outCmd,string filePath){//第一步:遍历对应协议配置文件夹 得到所有的配置文件DirectoryInfo directoryInfo = Directory.CreateDirectory(PROTO_PATH);//获取对应文件夹下所有文件的信息FileInfo[] files = directoryInfo.GetFiles();//遍历所有文件 为其生成协议脚本for (int i = 0; i < files.Length; i++){//后缀的判断 只有是配置文件才能用于生成if (files[i].Extension == ".proto"){//第二步:根据文件内容 来生成对应C#脚本(需要使用C#当中的Process类)Process cmd = new Process();//protoc.exe的路径cmd.StartInfo.FileName = PROTOC_PATH;//命令cmd.StartInfo.Arguments = $"-I={PROTO_PATH} --{outCmd}={filePath} {files[i]}";//执行cmd.Start();//告诉外部 某一个文件生成结束UnityEngine.Debug.Log(files[i] + "生成结束");}}UnityEngine.Debug.Log("所有内容生成结束");}
}

Protobuf-Net知识点

       //Protobuf的序列化和反序列化都要通过
        //流对象来进行处理
        //如果是进行本地存储,则可以使用文件流
        //如果是进行网络传输,则可以使用内存流获取字节数组

知识点一 序列化存储为本地文件

        //主要使用//1.生成的类中的 WriteTo方法//2.文件流FileStream对象TestMsg msg = new TestMsg();msg.ListInt.Add(1);msg.TestBool = false;msg.TestD = 5.5;msg.TestInt32 = 99;msg.TestMap.Add(1, "DamnF");msg.TestMsg2 = new TestMsg2();msg.TestMsg2.TestInt32 = 66;msg.TestHeart = new GameSystemTest.HeartMsg();msg.TestHeart.Time = 7777;using (FileStream fs = File.Create(Application.persistentDataPath + "/TestMsg.df")){msg.WriteTo(fs);}

知识点二 反序列化本地文件

       //主要使用//1.生成的类中的Parser.ParseFrom方法//2.文件流FileStream对象using (FileStream fs=File.OpenRead (Application.persistentDataPath + "/TestMsg.df")){TestMsg msg2 = null;msg2 = TestMsg.Parser.ParseFrom(fs);print(msg2.TestMap[1]);print(msg2.ListInt[0]);print(msg2.TestD);print(msg2.TestMsg2.TestInt32);print(msg2.TestHeart.Time);}

知识点三 得到序列化后的字节数组

   //主要使用//1.生成的类中的WriteTo方法//2.内存流MemoryStream对象byte[] bytes = null;using (MemoryStream ms=new MemoryStream ()){msg.WriteTo(ms);bytes = ms.ToArray();print("字节数组的长度" + bytes.Length);}

知识点四 从字节数组反序列化

       //主要使用//1.生成的类中的 Parser.ParserFrom方法//2.内存流MemoryStream对象using (MemoryStream ms=new MemoryStream (bytes)){print("内存流当中反序列化的内容");TestMsg msg2 = TestMsg.Parser.ParseFrom(ms);print(msg2.TestMap[1]);print(msg2.ListInt[0]);print(msg2.TestD);print(msg2.TestMsg2.TestInt32);print(msg2.TestHeart.Time);}

封装NetTool

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Google.Protobuf;
using UnityEngine;public static class NetTool
{public static byte[] GetProtoBytes(IMessage msg){//上节课学习的基础写法//byte[] bytes = null;//using (MemoryStream ms=new MemoryStream())//{//    msg.WriteTo(ms);//    bytes = ms.ToArray();//}//return bytes;//通过该拓展方法,就可以直接获取字节流对象return msg.ToByteArray();}public static T GetProtoMsg<T>(byte[]bytes)where T:class,IMessage{//得到对应消息的类型 通过反射得到内部的静态成员 然后得到其中对应的方法//进行反序列化Type type = typeof(T);//通过反射 得到对应的 静态成员属性对象PropertyInfo pInfp = type.GetProperty("Parser");object parseObj= pInfp.GetValue(null, null);//已经得到了该对象,那么可以得到该对象中 对应方法Type parserType = parseObj.GetType();//这是指定得到某一个重载方法MethodInfo mInfo = parserType.GetMethod("ParseFrom", new Type[] { typeof(byte[]) });//调用对应的方法 反序列化为指定的对象object msg= mInfo.Invoke(parseObj, new object[] { bytes });return msg as T;}
}

http://www.xdnf.cn/news/526357.html

相关文章:

  • 5G金融互联:迈向未来金融服务的极速与智能新时代
  • 判断三方库是64位还是32位
  • CVE-2015-3934 Fiyo CMS SQL注入
  • 代码随想录算法训练营Day37 | 完全背包基础理论 518. 零钱兑换II 377. 组合总和Ⅳ 57. 爬楼梯(第八期模拟笔试)
  • 网络协议之一根网线就能连接两台电脑?
  • Spring boot 学习笔记2
  • 易境通海外仓系统:一件代发全场景数字化解决方案
  • MySQL函数触发:函数处理与触发器自动化应用
  • 【Web渗透】DVWA搭建详细教程
  • NLP学习路线图(一): 线性代数(矩阵运算、特征值分解等)
  • MATLAB中islogical函数用法
  • wpf DataGrid 行选择事件
  • kafka 问与答
  • Cursor日常配置指南
  • CSS的padding属性设置探讨
  • uniapp vue 开发微信小程序 分包梳理经验总结
  • Java迭代器知识点详解
  • Linux动静态库制作与原理
  • Web前端开发:@media(媒体查询)
  • 构建高效移动端网页调试流程:以 WebDebugX 为核心的工具、技巧与实战经验
  • Agent的工作原理是什么?一文详解Agent的工作原理
  • MyBatis入门指南
  • 【计算机主板架构】ITX架构
  • [免费]苍穹微信小程序外卖点餐系统修改版(跑腿点餐系统)(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
  • 大模型(2)——提示工程(Prompt Engineering)
  • Qt与OpenGL绘制大全(加载obj模型文件、点、线、面、立方体、圆等)
  • 枪机定焦系统的自动控制装置
  • 健康生活指南:从日常细节开启养生之旅
  • RK3568下QT实现按钮切换tabWidget
  • CentOS7修改ip