项目中使用protobuf 3.0

protocol buffer从3.0 原生的compiler支持c++,Java,Python,Go,Ruby,JavaNano,JavaScript,Objective-C,C#,PHP这篇文章作为上一篇文章的补充,简单记录下一些变化。

protobuf的开源地址为:https://github.com/google/protobuf

protocol compiler下载地址为:https://github.com/google/protobuf/releases

官方定义message类型的例子:

syntax="proto3"

message SearchRequest{

  string query=1;

  int32 page_number=2;

  int32 result_per_page=3;

}

..proto文件的第一行指定使用proto3的语法。

特定语言的声明使用option关键定和选项名

option java_package="com.example.tutorial";//定义生成的java包

option java_outer_classname="AddressBookProtos";//定义java类名

option csharp_namespace="Google.Protobuf.Examples.AddressBook";//定义c#的命名空间

变化

1.字段前取消了required和optional两个关键字,目前可用的只有repeated关键字。

2.不可以现设置默认值了。

  a.string默认为空串

  b.枚举默认为第一个枚举定义的第一个值。并且必须是0

  c.bytes默认为空bytes

  d.bool默认为false

  e.数字类型默认为0

3.类型对应表

.proto Type Notes C++ Type Java Type Python Type[2] Go Type Ruby Type C# Type PHP Type
double   double double float float64 Float double float
float   float float float float32 Float float float
int32 Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. int32 int int int32 Fixnum or Bignum (as required) int integer
int64 Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. int64 long int/long[3] int64 Bignum long integer/string[5]
uint32 Uses variable-length encoding. uint32 int[1] int/long[3] uint32 Fixnum or Bignum (as required) uint integer
uint64 Uses variable-length encoding. uint64 long[1] int/long[3] uint64 Bignum ulong integer/string[5]
sint32 Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. int32 int int int32 Fixnum or Bignum (as required) int integer
sint64 Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. int64 long int/long[3] int64 Bignum long integer/string[5]
fixed32 Always four bytes. More efficient than uint32 if values are often greater than 228. uint32 int[1] int uint32 Fixnum or Bignum (as required) uint integer
fixed64 Always eight bytes. More efficient than uint64 if values are often greater than 256. uint64 long[1] int/long[3] uint64 Bignum ulong integer/string[5]
sfixed32 Always four bytes. int32 int int int32 Fixnum or Bignum (as required) int integer
sfixed64 Always eight bytes. int64 long int/long[3] int64 Bignum long integer/string[5]
bool   bool boolean bool bool TrueClass/FalseClass bool boolean
string A string must always contain UTF-8 encoded or 7-bit ASCII text. string String str/unicode[4] string String (UTF-8) string string
bytes May contain any arbitrary sequence of bytes. string ByteString str []byte String (ASCII-8BIT) ByteString string

proto代码编译

语法:

protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --javanano_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto

--proto_path 当proto文件中使用import时指定的导入文件的位置

--cpp_out c++输出目录

--java_out java输出目录

--python_out

--go_out

--ruby_out ruby输出目录

--objc_out oc输出目录

--csharp_out c#输出目录

path/to/file.proto为要编译的proto文件

使用

proto内容:

syntax="proto3";

option java_package="com.ztimage";
option java_outer_classname="WebUI";
option csharp_namespace="ZTImage.WebUI";
message SearchRequest{
string query=1;
int32 page_number=2;
int32 result_per_page=3;
}

执行命令:protoc --csharp_out d:/programs/protoc/bin WebUI.proto

生成代码:

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: WebUI.proto
#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 ZTImage.WebUI {

  /// <summary>Holder for reflection information generated from WebUI.proto</summary>
  public static partial class WebUIReflection {

    #region Descriptor
    /// <summary>File descriptor for WebUI.proto</summary>
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static WebUIReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "CgtXZWJVSS5wcm90byJMCg1TZWFyY2hSZXF1ZXN0Eg0KBXF1ZXJ5GAEgASgJ",
            "EhMKC3BhZ2VfbnVtYmVyGAIgASgFEhcKD3Jlc3VsdF9wZXJfcGFnZRgDIAEo",
            "BUIkCgtjb20uenRpbWFnZUIFV2ViVUmqAg1aVEltYWdlLldlYlVJYgZwcm90",
            "bzM="));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::ZTImage.WebUI.SearchRequest), global::ZTImage.WebUI.SearchRequest.Parser, new[]{ "Query", "PageNumber", "ResultPerPage" }, null, null, null)
          }));
    }
    #endregion

  }
  #region Messages
  public sealed partial class SearchRequest : pb::IMessage<SearchRequest> {
    private static readonly pb::MessageParser<SearchRequest> _parser = new pb::MessageParser<SearchRequest>(() => new SearchRequest());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<SearchRequest> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::ZTImage.WebUI.WebUIReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public SearchRequest() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public SearchRequest(SearchRequest other) : this() {
      query_ = other.query_;
      pageNumber_ = other.pageNumber_;
      resultPerPage_ = other.resultPerPage_;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public SearchRequest Clone() {
      return new SearchRequest(this);
    }

    /// <summary>Field number for the "query" field.</summary>
    public const int QueryFieldNumber = 1;
    private string query_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Query {
      get { return query_; }
      set {
        query_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "page_number" field.</summary>
    public const int PageNumberFieldNumber = 2;
    private int pageNumber_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int PageNumber {
      get { return pageNumber_; }
      set {
        pageNumber_ = value;
      }
    }

    /// <summary>Field number for the "result_per_page" field.</summary>
    public const int ResultPerPageFieldNumber = 3;
    private int resultPerPage_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int ResultPerPage {
      get { return resultPerPage_; }
      set {
        resultPerPage_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as SearchRequest);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(SearchRequest other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Query != other.Query) return false;
      if (PageNumber != other.PageNumber) return false;
      if (ResultPerPage != other.ResultPerPage) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Query.Length != 0) hash ^= Query.GetHashCode();
      if (PageNumber != 0) hash ^= PageNumber.GetHashCode();
      if (ResultPerPage != 0) hash ^= ResultPerPage.GetHashCode();
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Query.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Query);
      }
      if (PageNumber != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(PageNumber);
      }
      if (ResultPerPage != 0) {
        output.WriteRawTag(24);
        output.WriteInt32(ResultPerPage);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Query.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Query);
      }
      if (PageNumber != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(PageNumber);
      }
      if (ResultPerPage != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(ResultPerPage);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(SearchRequest other) {
      if (other == null) {
        return;
      }
      if (other.Query.Length != 0) {
        Query = other.Query;
      }
      if (other.PageNumber != 0) {
        PageNumber = other.PageNumber;
      }
      if (other.ResultPerPage != 0) {
        ResultPerPage = other.ResultPerPage;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            Query = input.ReadString();
            break;
          }
          case 16: {
            PageNumber = input.ReadInt32();
            break;
          }
          case 24: {
            ResultPerPage = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  #endregion

}

#endregion Designer generated code

在项目中引用Google.Protobuf程序集,生成的代码放到项目中

测试代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Google.Protobuf;

namespace ZTImage.WebUI
{
    class Program
    {
        static void Main(string[] args)
        {
            SearchRequest request = new SearchRequest() {
                Query="age>0 and age <18",
                PageNumber=1,
                ResultPerPage=50
            };

            using (var output = File.Create("mr.dat"))
            {
                request.WriteTo(output);
            }

            SearchRequest sr = null;
            using (var input = File.OpenRead("mr.dat"))
            {
                sr = SearchRequest.Parser.ParseFrom(input);
            }

            Console.WriteLine("Query:{0},PageNumber:{1},ResultPerPage:{2}",sr.Query,sr.PageNumber,sr.ResultPerPage);
            Console.ReadKey();

        }
    }
}

结果:

Query:age>0 and age <18,PageNumber:1,ResultPerPage:50

pref:

500W writer 2022ms read 1864ms

时间: 2024-10-13 22:51:57

项目中使用protobuf 3.0的相关文章

在erlang项目中使用protobuf

在erlang项目中使用protobuf http://blog.csdn.net/mycwq/article/details/21864191 protobuf是google的一个序列化框架,类似XML,JSON,其特点是基于二进制,比XML表示同样一段内容要短小得多,还可以定义一些可选字段,广泛用于服务端与客户端通信.文章将着重介绍在erlang中如何使用protobuf. 首先google没有提供对erlang语言的直接支持,所以这里使用到的第三方的protobuf库(erlang_pro

项目中使用protobuf

在互种系统中数据通信或数据交换可以使用protobuf,他比json.xml的数据量要小一些. 另外因为消息要单独写一个.proto文件,来生成各平台的代码,所以对跨平台通信来说也比较友好. 一.使用方法 1.编写.proto文件,定义格式 2.用所需源文件的编译器编译.proto文件,生成所需的源文件,官方的编译器只支持  ,c++.java.python,c#可以用:https://github.com/mgravell/protobuf-net 或者用我编译好的:http://pan.ba

项目中处理android 6.0权限管理问题

android 6.0对于权限管理比较收紧,因此在适配android 6.0的时候就很有必要考虑一些权限管理的问题. 如果你没适配6.0的设备并且权限没给的话,就会出现类似如下的问题: java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:xxxxxxxxxxx cmp=com.android.server.telecom/.componen

Erlang 在erlang项目中使用protobuf

protobuf是google的一个序列化框架,类似XML,JSON,其特点是基于二进制,比XML表示同样一段内容要短小得多,还可以定义一些可选字段,广泛用于服务端与客户端通信.文章将着重介绍在erlang中如何使用protobuf. 首先google没有提供对erlang语言的直接支持,所以这里使用到的第三方的protobuf库( erlang_protobuffs ) 定义一个protobuf结构,保存为test.proto,如下: message Person { required int

在java项目中使用protobuf

1 通用方式 第一步,定义数据结构 第二步,使用protoc.exe生成java代码 第三步,序列化 第四步,反序列化 2 grpc方式 grpc官方推荐的方式,通过maven插件来生成java代码. 参考 https://www.cnblogs.com/liugh/p/7505533.html 原文地址:https://www.cnblogs.com/hustdc/p/9131346.html

主攻ASP.NET.4.5.1 MVC5.0之重生:在项目中使用zTree jQuery 树插件

效果图和json格式 Controllers代码 using HR.Models; using HR.Models.Repository; /************************************************************************************ * 命名空间:HR.Controllers * Controller: TreeController * 版本号: F 1.0.0.0 * 负责人: Markfan * 电子邮箱:[ema

采用EntLib5.0(Unity+Interception+Caching)实现项目中可用的Caching机制

看了园子里很多介绍Caching的文章,多数都只介绍基本机制,对于Cache更新和依赖部分,更是只简单的实现ICacheItemRefreshAction接口,这在实际项目中是远远不够的.实际项目中,至少应该考虑以下3点: 外部数据:通过外部服务,从其他系统取来的数据.我们无法控制,也不知道啥时候会被更新.对于这部分数据,我们采用定时更新的策略,默认1小时更新1次,可配置. 内部数据:系统自己产生的数据,可以完全掌控.对这部分数据,我们实现ICacheItemRefreshAction接口,一旦

spring3.0结合Redis在项目中的运用

推荐一个程序员的论坛网站:http://ourcoders.com/home/ 以下内容使用到的技术有:Redis缓存.SpringMVC.Maven.项目中使用了redis缓存,目的是在业务场景中,提高SQL的查询效率,做出性能优化.先看pom.xml的配置文件中,Jedis是Redis的Java客户端,Jedis基本实现了Redis的所有功能.在使用的时候,我们创建一个Jedis对象,通过操作Jedis来操作Redis,实现我们的业务场景需求.项目中使用了Maven来托管,先看Jedis在p

ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package

目前在学习ASP.NET CORE MVC中,今天看到微软在ASP.NET CORE MVC 2.0中又恢复了允许开发人员引用第三方DLL程序集的功能,感到甚是高兴!于是我急忙写了个Demo想试试,我的项目结构如下: 可以看到解决方案中就两个项目,AspNetCoreWebApp就是一个ASP.NET CORE MVC 2.0的项目,而MyNetCoreLib是一个.Net Core 2.0的类库项目,为了体现AspNetCoreWebApp是通过程序集来引用MyNetCoreLib的,我还在解