iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Protobuf工具在C#中的使用方法是什么
  • 918
分享到

Protobuf工具在C#中的使用方法是什么

2023-06-21 20:06:02 918人浏览 安东尼
摘要

这篇文章主要讲解了“Protobuf工具在C#中的使用方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Protobuf工具在C#中的使用方法是什么”吧!protobuf是一个语言无关

这篇文章主要讲解了“Protobuf工具C#中的使用方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Protobuf工具在C#中的使用方法是什么”吧!

protobuf是一个语言无关、平台无关的序列化协议,由谷歌开源提供。再加上其高性能、存储占用更小等特点,在云原生的应用中越来越广泛。

在C#中主要有两种方法来使用protobuf协议,nuget包分别为Google.Protobufprotobuf-net,其中Google.Protobuf由谷歌官方提供。

项目资料及文档

  • 项目官网:https://developers.google.cn/protocol-buffers?hl=zh-cn

  • GitHub主页:Https://github.com/protocolbuffers/protobuf/

  • 官方文档:https://developers.google.cn/protocol-buffers/docs/overview?hl=zh-cn

  • 该nuget包支持.netFramework 4.5、.NETStandard1.1、.net5等

准备工作

需要用到的nuget有如下两个:Google.ProtobufGoogle.Protobuf.Tools,其中Google.Protobuf是主类库,运行时要用到。Google.Protobuf.Tools提供了命令行工具,用于根据.proto文件转为目标语言的类型,仅开发时使用,运行时不需要。

本次Demo使用的.proto文件内容如下:

syntax = "proto3";option cc_enable_arenas = true;package Tccc.Demo.Protobuf;message ErrorLog {    string LogID = 1;    string Context = 2;    string Stack = 3;}

首先需要根据.proto文件生成目标类型,操作如下:

./google.protobuf.tools\3.19.1\tools\windows_x64\protoc.exe --csharp_out=./generatedCode ./proto/ErrorLog.proto

其中--csharp_out选项是生成C#语言的目标类型,运行protoc.exe -h 查看帮助信息,可以看到还支持一下几种选项:

--proto_path=PATH--cpp_out=OUT_DIR Generate c++ header and source.--csharp_out=OUT_DIR Generate C# source file.--java_out=OUT_DIR Generate Java source file.--js_out=OUT_DIR Generate javascript source.--Kotlin_out=OUT_DIR Generate Kotlin file.--objc_out=OUT_DIR Generate Objective-C header and source.--PHP_out=OUT_DIR Generate php source file.--python_out=OUT_DIR Generate Python source file.--ruby_out=OUT_DIR Generate Ruby source file.

运行上述命令,会根据指定的ErrorLog.proto文件生成ErrorLog.cs文件,文件中就是C#类型ErrorLog。生成的代码中会给此类型增加方法void WriteTo(CodedOutputStream output)和只读属性Parser,接下来进行序列化和反序列化的关键。

生成的ErrorLog类的完整代码:

// <auto-generated>//     Generated by the protocol buffer compiler.  DO NOT EDIT!//     source: ProtoFiles/ErrorLog.proto// </auto-generated>#pragma warning disable 1591, 0612, 3021#region Designer generated codeusing pb = global::Google.Protobuf;using pbc = global::Google.Protobuf.Collections;using pbr = global::Google.Protobuf.Reflection;using scg = global::System.Collections.Generic;namespace Tccc.Demo.Protobuf {  /// <summary>Holder for reflection infORMation generated from ProtoFiles/ErrorLog.proto</summary>  public static partial class ErrorLogReflection {    #region Descriptor    /// <summary>File descriptor for ProtoFiles/ErrorLog.proto</summary>    public static pbr::FileDescriptor Descriptor {      get { return descriptor; }    }    private static pbr::FileDescriptor descriptor;    static ErrorLogReflection() {      byte[] descriptorData = global::System.Convert.FromBase64String(          string.Concat(            "ChlQcm90b0ZpbGVzL0Vycm9yTG9nLnByb3RvEhJUY2NjLkRlbW8uUHJvdG9i",            "dWYiOQoIRXJyb3JMb2cSDQoFTG9nSUQYASABKAkSDwoHQ29udGV4dBGCIAEo",            "CRINCgVTdGFjaxgDIAEoCUID+AEBYgZwcm90bzM="));      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,          new pbr::FileDescriptor[] { },          new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {            new pbr::GeneratedClrTypeInfo(typeof(global::Tccc.Demo.Protobuf.ErrorLog), global::Tccc.Demo.Protobuf.ErrorLog.Parser, new[]{ "LogID", "Context", "Stack" }, null, null, null, null)          }));    }    #endregion  }  #region Messages  public sealed partial class ErrorLog : pb::IMessage<ErrorLog>  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE      , pb::IBufferMessage  #endif  {    private static readonly pb::MessageParser<ErrorLog> _parser = new pb::MessageParser<ErrorLog>(() => new ErrorLog());    private pb::UnknownFieldSet _unknownFields;    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public static pb::MessageParser<ErrorLog> Parser { get { return _parser; } }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public static pbr::MessageDescriptor Descriptor {      get { return global::Tccc.Demo.Protobuf.ErrorLogReflection.Descriptor.MessageTypes[0]; }    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    pbr::MessageDescriptor pb::IMessage.Descriptor {      get { return Descriptor; }    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public ErrorLog() {      OnConstruction();    }    partial void OnConstruction();    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public ErrorLog(ErrorLog other) : this() {      logID_ = other.logID_;      context_ = other.context_;      stack_ = other.stack_;      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public ErrorLog Clone() {      return new ErrorLog(this);    }    /// <summary>Field number for the "LogID" field.</summary>    public const int LogIDFieldNumber = 1;    private string logID_ = "";    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public string LogID {      get { return logID_; }      set {        logID_ = pb::ProtoPreconditions.CheckNotNull(value, "value");      }    }    /// <summary>Field number for the "Context" field.</summary>    public const int ContextFieldNumber = 2;    private string context_ = "";    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public string Context {      get { return context_; }      set {        context_ = pb::ProtoPreconditions.CheckNotNull(value, "value");      }    }    /// <summary>Field number for the "Stack" field.</summary>    public const int StackFieldNumber = 3;    private string stack_ = "";    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public string Stack {      get { return stack_; }      set {        stack_ = pb::ProtoPreconditions.CheckNotNull(value, "value");      }    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public override bool Equals(object other) {      return Equals(other as ErrorLog);    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public bool Equals(ErrorLog other) {      if (ReferenceEquals(other, null)) {        return false;      }      if (ReferenceEquals(other, this)) {        return true;      }      if (LogID != other.LogID) return false;      if (Context != other.Context) return false;      if (Stack != other.Stack) return false;      return Equals(_unknownFields, other._unknownFields);    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public override int GetHashCode() {      int hash = 1;      if (LogID.Length != 0) hash ^= LogID.GetHashCode();      if (Context.Length != 0) hash ^= Context.GetHashCode();      if (Stack.Length != 0) hash ^= Stack.GetHashCode();      if (_unknownFields != null) {        hash ^= _unknownFields.GetHashCode();      }      return hash;    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public override string ToString() {      return pb::JSONFormatter.ToDiagnosticString(this);    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public void WriteTo(pb::CodedOutputStream output) {    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE      output.WriteRawMessage(this);    #else      if (LogID.Length != 0) {        output.WriteRawTag(10);        output.WriteString(LogID);      }      if (Context.Length != 0) {        output.WriteRawTag(18);        output.WriteString(Context);      }      if (Stack.Length != 0) {        output.WriteRawTag(26);        output.WriteString(Stack);      }      if (_unknownFields != null) {        _unknownFields.WriteTo(output);      }    #endif    }    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {      if (LogID.Length != 0) {        output.WriteRawTag(10);        output.WriteString(LogID);      }      if (Context.Length != 0) {        output.WriteRawTag(18);        output.WriteString(Context);      }      if (Stack.Length != 0) {        output.WriteRawTag(26);        output.WriteString(Stack);      }      if (_unknownFields != null) {        _unknownFields.WriteTo(ref output);      }    }    #endif    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public int CalculateSize() {      int size = 0;      if (LogID.Length != 0) {        size += 1 + pb::CodedOutputStream.ComputeStringSize(LogID);      }      if (Context.Length != 0) {        size += 1 + pb::CodedOutputStream.ComputeStringSize(Context);      }      if (Stack.Length != 0) {        size += 1 + pb::CodedOutputStream.ComputeStringSize(Stack);      }      if (_unknownFields != null) {        size += _unknownFields.CalculateSize();      }      return size;    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public void MergeFrom(ErrorLog other) {      if (other == null) {        return;      }      if (other.LogID.Length != 0) {        LogID = other.LogID;      }      if (other.Context.Length != 0) {        Context = other.Context;      }      if (other.Stack.Length != 0) {        Stack = other.Stack;      }      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);    }    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    public void MergeFrom(pb::CodedInputStream input) {    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE      input.ReadRawMessage(this);    #else      uint tag;      while ((tag = input.ReadTag()) != 0) {        switch(tag) {          default:            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);            break;          case 10: {            LogID = input.ReadString();            break;          }          case 18: {            Context = input.ReadString();            break;          }          case 26: {            Stack = input.ReadString();            break;          }        }      }    #endif    }    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {      uint tag;      while ((tag = input.ReadTag()) != 0) {        switch(tag) {          default:            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);            break;          case 10: {            LogID = input.ReadString();            break;          }          case 18: {            Context = input.ReadString();            break;          }          case 26: {            Stack = input.ReadString();            break;          }        }      }    }    #endif  }  #endregion}#endregion Designer generated code

序列化操作

public static byte[] Serialize(ErrorLog log)        {            using (MemoryStream output = new MemoryStream())            {                log.WriteTo(output);                return output.ToArray();            }        }

反序列化操作

ErrorLog desErrorLog= ErrorLog.Parser.ParseFrom(data);

使用特点和理解

  • protoc.exe是支持生成多语言类型,这对于跨语言的混合编程比较方便。

  • 根据上述使用步骤可以看到,必须先使用工具protoc生成目标类型,才能调用序列化和反序列化方法,这有些不符合.net平台的编码习惯。

  • 一堆自动生成的C#类在可维护性方面欠佳,当需要调整属性字段时,还要通过工具重新生成,较为麻烦。

感谢各位的阅读,以上就是“Protobuf工具在C#中的使用方法是什么”的内容了,经过本文的学习后,相信大家对Protobuf工具在C#中的使用方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: Protobuf工具在C#中的使用方法是什么

本文链接: https://www.lsjlt.com/news/300454.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Protobuf工具在C#中的使用方法是什么
    这篇文章主要讲解了“Protobuf工具在C#中的使用方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Protobuf工具在C#中的使用方法是什么”吧!protobuf是一个语言无关...
    99+
    2023-06-21
  • c++中protobuf的用法是什么
    在C++中使用protobuf,首先需要定义一个.proto文件来描述消息的结构,然后使用protobuf的编译器生成对应的C++代...
    99+
    2024-03-05
    c++
  • Google.Protobuf工具在C#中的使用方法
    protobuf是一个语言无关、平台无关的序列化协议,由谷歌开源提供。再加上其高性能、存储占用更小等特点,在云原生的应用中越来越广泛。 在C#中主要有两种方法来使用protobuf协...
    99+
    2024-04-02
  • mongodb工具使用的方法是什么
    MongoDB是一个非关系型数据库,它提供了一些工具来与数据库进行交互和管理。以下是一些常用的MongoDB工具的使用方法:1. M...
    99+
    2023-09-12
    mongodb
  • c++中protobuf的作用是什么
    在C++中,Protobuf(Protocol Buffers)的作用是用于序列化结构化数据,以便在不同系统之间进行数据交换或持久化...
    99+
    2024-03-05
    c++
  • Linux命令工具的使用方法是什么
    这篇文章给大家介绍Linux命令工具的使用方法是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Linux 上有太多的命令了,如果背的话不知道得背到什么时候,但是Linux中有 Bash 命令历史以及像 apropo...
    99+
    2023-06-28
  • MySQL中explain工具的用法是什么
    在MySQL中,EXPLAIN是一种用于查询优化的工具。它可以帮助开发人员和数据库管理员分析查询语句的执行计划,了解MySQL是如何...
    99+
    2024-04-09
    MySQL explain
  • Protobuf在Cmake中的正确使用方法详解
    Protobuf是google开发的一个序列化和反序列化的协议库,我们可以自己设计传递数据的格式,通过.proto文件定义我们的要传递的数据格式。例如,在深度学习中常用的ONNX交换...
    99+
    2024-04-02
  • 在Linux下HTTPie工具的使用方法
    本篇内容主要讲解“在Linux下HTTPie工具的使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“在Linux下HTTPie工具的使用方法”吧!如果你经常需要通过终端以非交互模式访问网络服...
    99+
    2023-06-13
  • c#中epplus的使用方法是什么
    EPPlus是一个用于处理Excel文件的开源库,可以在C#中使用。以下是一些EPPlus的使用方法: 创建一个新的Excel文件...
    99+
    2024-03-04
    c#
  • c#中intersect的使用方法是什么
    在C#中,可以使用LINQ的Intersect方法来获取两个集合的交集。Intersect方法接受一个IEnumerable类型的参...
    99+
    2024-04-02
  • c#中brush的使用方法是什么
    在C#中,Brush类表示用于填充图形或文本的颜色和纹理。使用Brush的方法如下: 创建Brush对象: SolidBrush...
    99+
    2024-04-09
    c#
  • c#中signalr的使用方法是什么
    SignalR 是一个用于实时 web 应用程序的库,可以在客户端和服务器之间实现实时通信。在 C# 中使用 SignalR 有以下...
    99+
    2024-03-06
    c#
  • C#中ManualResetEvent的使用方法是什么
    在C#中,ManualResetEvent 是一个同步基元,允许一个线程通知另一个线程,某个事件已经发生。主要有以下几个方法: M...
    99+
    2024-03-08
    C#
  • c#中itextsharp的使用方法是什么
    在C#中使用iTextSharp主要涉及创建、读取和操作PDF文件。以下是一些常见的用法: 创建PDF文件:可以使用iTextSh...
    99+
    2024-04-02
  • c#中httpserver的使用方法是什么
    在C#中使用HttpServer,可以通过.Net Framework提供的HttpListener类来实现。下面是一个简单的示例代...
    99+
    2024-04-02
  • c#中filter的使用方法是什么
    在C#中,可以使用LINQ(Language Integrated Query)来实现过滤数据,其中filter的功能由Wher&#...
    99+
    2024-04-02
  • c#中operator的使用方法是什么
    在C#中,operator是用于执行特定操作的关键词。C#中的内置运算符包括算术运算符(如加法、减法、乘法、除法)、比较运算符(如大...
    99+
    2024-04-02
  • c#中progressbar的使用方法是什么
    在C#中,可以使用ProgressBar控件来显示进度条。以下是ProgressBar控件的使用方法: 首先,在窗体的设计器中拖...
    99+
    2024-03-15
    c# progressbar
  • c#中emit的使用方法是什么
    在C#中,emit是一个动态生成IL代码的技术,通常与反射和动态代码生成结合使用。通过emit,我们可以在运行时动态创建和修改程序集...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作