项目中使用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[]; }
} [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 = ;
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 = ;
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 = ;
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 = ;
if (Query.Length != ) hash ^= Query.GetHashCode();
if (PageNumber != ) hash ^= PageNumber.GetHashCode();
if (ResultPerPage != ) 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 != ) {
output.WriteRawTag();
output.WriteString(Query);
}
if (PageNumber != ) {
output.WriteRawTag();
output.WriteInt32(PageNumber);
}
if (ResultPerPage != ) {
output.WriteRawTag();
output.WriteInt32(ResultPerPage);
}
} [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = ;
if (Query.Length != ) {
size += + pb::CodedOutputStream.ComputeStringSize(Query);
}
if (PageNumber != ) {
size += + pb::CodedOutputStream.ComputeInt32Size(PageNumber);
}
if (ResultPerPage != ) {
size += + pb::CodedOutputStream.ComputeInt32Size(ResultPerPage);
}
return size;
} [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(SearchRequest other) {
if (other == null) {
return;
}
if (other.Query.Length != ) {
Query = other.Query;
}
if (other.PageNumber != ) {
PageNumber = other.PageNumber;
}
if (other.ResultPerPage != ) {
ResultPerPage = other.ResultPerPage;
}
} [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != ) {
switch(tag) {
default:
input.SkipLastField();
break;
case : {
Query = input.ReadString();
break;
}
case : {
PageNumber = input.ReadInt32();
break;
}
case : {
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=,
ResultPerPage=
}; 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
项目中使用protobuf 3.0的更多相关文章
- 在erlang项目中使用protobuf
在erlang项目中使用protobuf http://blog.csdn.net/mycwq/article/details/21864191 protobuf是google的一个序列化框架,类似X ...
- 项目中使用protobuf
在互种系统中数据通信或数据交换可以使用protobuf,他比json.xml的数据量要小一些. 另外因为消息要单独写一个.proto文件,来生成各平台的代码,所以对跨平台通信来说也比较友好. 一.使用 ...
- 项目中处理android 6.0权限管理问题
android 6.0对于权限管理比较收紧,因此在适配android 6.0的时候就很有必要考虑一些权限管理的问题. 如果你没适配6.0的设备并且权限没给的话,就会出现类似如下的问题: java.la ...
- 实战派 | Java项目中玩转Redis6.0客户端缓存!
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. 在前面的文章中,我们介绍了Redis6.0中的新特性客户端缓存client-side caching,通过tel ...
- Erlang 在erlang项目中使用protobuf
protobuf是google的一个序列化框架,类似XML,JSON,其特点是基于二进制,比XML表示同样一段内容要短小得多,还可以定义一些可选字段,广泛用于服务端与客户端通信.文章将着重介绍在erl ...
- 在java项目中使用protobuf
1 通用方式 第一步,定义数据结构 第二步,使用protoc.exe生成java代码 第三步,序列化 第四步,反序列化 2 grpc方式 grpc官方推荐的方式,通过maven插件来生成java代码. ...
- spring3.0结合Redis在项目中的运用
推荐一个程序员的论坛网站:http://ourcoders.com/home/ 以下内容使用到的技术有:Redis缓存.SpringMVC.Maven.项目中使用了redis缓存,目的是在业务场景中, ...
- 采用EntLib5.0(Unity+Interception+Caching)实现项目中可用的Caching机制
看了园子里很多介绍Caching的文章,多数都只介绍基本机制,对于Cache更新和依赖部分,更是只简单的实现ICacheItemRefreshAction接口,这在实际项目中是远远不够的.实际项目中, ...
- 无法安装程序包“MIcrosoft.Owin.Security 2.0.2”。您正在尝试将此程序包安装到某个将“.NETFramework,Version=v4.0”作为目标的项目中。
在VS2010 MVC4项目中,安装NuGet程序包Microsoft.AspNet.SignalR时出现以下错误: 原因是安装的版本是Microsoft.AspNet.SignalR 2.0.2,要 ...
随机推荐
- 如何在单片机上使用printf函数(printf)(avr)(stm)(lpc)(单片机)(转)
摘要: 当我们在调试代码时,通常需要将程序中的某个变量打印至PC机上,来判断我们的程序是否按预期的运行,printf函数很好的做到了这一点,它能直接以字符的方式输出变量名和变量的值,printf ...
- (三)微信小程序之发送服务通知(模板消息)
1.后端获取AccessToken返回给微信端 微信小程序端请求后端得到AccessToken 2.后端获取openid返回给微信端 微信小程序端登录请求后端得到openid 3.发送消息 ...
- 谷歌Volley网络框架讲解——HttpStack及其实现类
前两篇已经对网络请求流程已经梳理了个大概,这次我们着重看一下HttpStack和它的其实现类.我们之前在Network篇讲过它仅有一个实现类,而今天我们讲的HttpStack有两个实现类. 其中Htt ...
- JQuery中$.ajax()方法参数详解 转载
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- Request.getRequestURL
getRequestURI()就相当于你在写一个JSP页面的时候会有这样的东西"action='/WebRoot/xxx'"这个方法就是获得'/WebRoot/xxx',也就是说它 ...
- SpringData JPA查询分页demo
SpringData JPA 的 PagingAndSortingRepository接口已经提供了对分页的支持,查询的时候我们只需要传入一个 org.springframework.data.dom ...
- [UML]UML 教程 - 第二部分
UML作为软件开发典型的开发过程 业务过程模型创建 业务过程模型被用来定义发生在企业或组织内部的高级业务活动和业务过程,并且是建立用例模型的基础.一般来说业务过程模型比一个软件系统所能实现的更多(比如 ...
- 精简的webservice
看了网上好多关于webservice的例子,基本上对初学者来说都是模棱两可云里雾里,现在,我将网上关于webservice的讲解提炼出来,通过一个最简单使用并且方便的例子,告诉大家什么是webserv ...
- Scikit Learn安装教程
Windows下安装scikit-learn 准备工作 Python (>= 2.6 or >= 3.3), Numpy (>= 1.6.1) Scipy (>= 0.9), ...
- SQL中distinct的用法(转载)
1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值.关键词 ...