欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Google.Protobuf工具在C#中的使用方法

 更新時(shí)間:2021年11月24日 16:01:31   作者:chenzk  
本文詳細(xì)講解了Google.Protobuf工具在C#中的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

protobuf是一個(gè)語(yǔ)言無(wú)關(guān)、平臺(tái)無(wú)關(guān)的序列化協(xié)議,由谷歌開(kāi)源提供。再加上其高性能、存儲(chǔ)占用更小等特點(diǎn),在云原生的應(yīng)用中越來(lái)越廣泛。

在C#中主要有兩種方法來(lái)使用protobuf協(xié)議,nuget包分別為Google.Protobufprotobuf-net,其中Google.Protobuf由谷歌官方提供。本文簡(jiǎn)要記錄和展示Google.Protobuf的使用方法和特點(diǎn)。

項(xiàng)目資料及文檔

  • 項(xiàng)目官網(wǎng):https://developers.google.cn/protocol-buffers?hl=zh-cn
  • github主頁(yè):https://github.com/protocolbuffers/protobuf/
  • 官方文檔:https://developers.google.cn/protocol-buffers/docs/overview?hl=zh-cn
  • 該nuget包支持.NETFramework 4.5、.NETStandard1.1、.net5等

準(zhǔn)備工作

需要用到的nuget有如下兩個(gè):Google.Protobuf、Google.Protobuf.Tools,其中Google.Protobuf是主類(lèi)庫(kù),運(yùn)行時(shí)要用到。Google.Protobuf.Tools提供了命令行工具,用于根據(jù).proto文件轉(zhuǎn)為目標(biāo)語(yǔ)言的類(lèi)型,僅開(kāi)發(fā)時(shí)使用,運(yùn)行時(shí)不需要。

本次Demo使用的.proto文件內(nèi)容如下:

syntax = "proto3";
option cc_enable_arenas = true;

package Tccc.Demo.Protobuf;

message ErrorLog {
    string LogID = 1;
    string Context = 2;
    string Stack = 3;
}

首先需要根據(jù).proto文件生成目標(biāo)類(lèi)型,操作如下:

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

其中--csharp_out選項(xiàng)是生成C#語(yǔ)言的目標(biāo)類(lèi)型,運(yùn)行protoc.exe -h 查看幫助信息,可以看到還支持一下幾種選項(xiàng):

--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.

運(yùn)行上述命令,會(huì)根據(jù)指定的ErrorLog.proto文件生成ErrorLog.cs文件,文件中就是C#類(lèi)型ErrorLog。生成的代碼中會(huì)給此類(lèi)型增加方法void WriteTo(CodedOutputStream output)和只讀屬性Parser,接下來(lái)進(jìn)行序列化和反序列化的關(guān)鍵。

生成的ErrorLog類(lèi)的完整代碼:

// <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 code

using 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);

使用特點(diǎn)和理解

  • protoc.exe是支持生成多語(yǔ)言類(lèi)型,這對(duì)于跨語(yǔ)言的混合編程比較方便。
  • 根據(jù)上述使用步驟可以看到,必須先使用工具protoc生成目標(biāo)類(lèi)型,才能調(diào)用序列化和反序列化方法,這有些不符合.net平臺(tái)的編碼習(xí)慣。
  • 一堆自動(dòng)生成的C#類(lèi)在可維護(hù)性方面欠佳,當(dāng)需要調(diào)整屬性字段時(shí),還要通過(guò)工具重新生成,較為麻煩。

到此這篇關(guān)于Google.Protobuf工具在C#中的使用方法就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#使用后臺(tái)線程BackgroundWorker處理任務(wù)的總結(jié)

    C#使用后臺(tái)線程BackgroundWorker處理任務(wù)的總結(jié)

    這篇文章主要介紹了C#使用后臺(tái)線程BackgroundWorker處理任務(wù)的總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • C#將Sql數(shù)據(jù)保存到Excel文件中的方法

    C#將Sql數(shù)據(jù)保存到Excel文件中的方法

    這篇文章主要介紹了C#將Sql數(shù)據(jù)保存到Excel文件中的方法,文中的ExportExcel可起到將sql數(shù)據(jù)導(dǎo)出為Excel的作用,需要的朋友可以參考下
    2014-08-08
  • C#計(jì)算矩陣的逆矩陣方法實(shí)例分析

    C#計(jì)算矩陣的逆矩陣方法實(shí)例分析

    這篇文章主要介紹了C#計(jì)算矩陣的逆矩陣方法,較為詳細(xì)的分析了逆矩陣的計(jì)算原理與相關(guān)的C#實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • Response.Redirect 正在中止線程解決方案

    Response.Redirect 正在中止線程解決方案

    這兩天在開(kāi)發(fā)調(diào)試過(guò)程中,老是會(huì)出現(xiàn)在一個(gè) "正在中止線程“(ThreadAbortException)的例外信息,很是疑惑,于是網(wǎng)上收集整理了一下,現(xiàn)在曬出來(lái)和大家分享,希望對(duì)你們有幫助
    2012-11-11
  • C#實(shí)現(xiàn)windows系統(tǒng)重啟和關(guān)機(jī)的代碼詳解

    C#實(shí)現(xiàn)windows系統(tǒng)重啟和關(guān)機(jī)的代碼詳解

    這篇文章主要介紹了C#實(shí)現(xiàn)windows系統(tǒng)重啟和關(guān)機(jī)的的方法,涉及C#調(diào)用windows系統(tǒng)命令實(shí)現(xiàn)控制開(kāi)機(jī)、關(guān)機(jī)等操作的技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2024-02-02
  • 如何最大限度地降低多線程C#代碼的復(fù)雜性

    如何最大限度地降低多線程C#代碼的復(fù)雜性

    這篇文章主要介紹了如何最大限度地降低多線程C#代碼的復(fù)雜性,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • C# 調(diào)用Delphi dll 實(shí)例代碼

    C# 調(diào)用Delphi dll 實(shí)例代碼

    這篇文章介紹了C# 調(diào)用Delphi dll 實(shí)例代碼,有需要的朋友可以參考一下
    2013-09-09
  • C#?二進(jìn)制序列化和反序列化的具體實(shí)現(xiàn)

    C#?二進(jìn)制序列化和反序列化的具體實(shí)現(xiàn)

    本文主要介紹了C#?二進(jìn)制序列化和反序列化的具體實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C#遍歷系統(tǒng)進(jìn)程的方法

    C#遍歷系統(tǒng)進(jìn)程的方法

    這篇文章主要介紹了C#遍歷系統(tǒng)進(jìn)程的方法,涉及C#底層操作獲取系統(tǒng)信息與硬件信息的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • unity 文件流讀取圖片與www讀取圖片的區(qū)別介紹

    unity 文件流讀取圖片與www讀取圖片的區(qū)別介紹

    這篇文章主要介紹了unity 文件流讀取圖片與www讀取圖片的對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04

最新評(píng)論