为什么google protobuf不支持map的protobuf序列化原理和反protobuf序列化原理

posts - 155,&
comments - 600,&
trackbacks - 0
3112345678910111213141516171819202122232425262728291234567891011
留言簿(40)
随笔分类(144)
随笔档案(109)
文章档案(1)
积分与排名
阅读排行榜
评论排行榜
jprotobufA very useful utility library for java programmer using google protobuf &jprotobuf是针对Java程序开发一套简易类库,目的是简化java语言对protobuf类库的使用使用jprotobuf可以无需再去了解.proto文件操作与语法,直接使用java注解定义字段类型即可。1.0.0 支持普通类型,嵌套对象以及对象数组的Protobuf协议的序列化与反序列化实现。1.0.1 由注解对象动态生成Protobuf的IDL描述文件内容。1.0.3 增加由.proto 描述文件动态生成Protobuf操作对象的支持,详见下面使用说明。环境要求J DK 6 或以上版本&API使用说明示例:假如需要定义protobuf定义一个数据接口,包含两个属性,一个是string,一个是int32传统protobuf使用过程a 定义.proto说明文件. test.protopackage&pkg;&&option&java_package&=&"com.baidu.bjf.remoting.protobuf";//这里声明输出的java的类名&&option&java_outer_classname&=&"SimpleTypeTest";&&message&InterClassName&{&&&&required&string&name&=&1;&&required&int32&&value&=&2;&} &b 使用protoc.exe 编译.proto文件protoc&--java_out=src&&test.protoc 编译生成的Java文件,利用protobuf API进行序列化与反序化操作序列化操作:InterClassName&icn&=&InterClassName.newBuilder().setName("abc")&&&&&&&&.setValue(100).build();&&&&&&&&byte[]&bb&=&icn.toByteArray();反序化操作byte[]&bb&=&;InterClassName&icn&=&InterClassName.parseFrom(bb);&使用jprotobuf API 简化开发a 使用注解直接使用pojo对象import&com.baidu.bjf.remoting.protobuf.FieldTimport&com.baidu.bjf.remoting.protobuf.annotation.P/**&*&A&simple&jprotobuf&pojo&class&just&for&demo.&*&&*&@author&xiemalin&*&@since&1.0.0&*/public&class&SimpleTypeTest&{&&&&@Protobuf(fieldType&=&FieldType.STRING,&order&=&1,&required&=&true)&&&&private&String&&&&&@Protobuf(fieldType&=&FieldType.INT32,&order&=&2,&required&=&false)&&&&private&int&&&&&public&int&getValue()&{&&&&&&&&return&&&&&}&&&&public&void&setValue(int&value)&{&&&&&&&&this.value&=&&&&&}}b 使用jprotobuf API进行序列化与反序列化操作&Codec&SimpleTypeTest&&simpleTypeCodec&=&ProtobufProxy&&&&&&&&&&&&&&&&.create(SimpleTypeTest.class);&&&&&&&&SimpleTypeTest&stt&=&new&SimpleTypeTest();&&&&&&&&stt.name&=&"abc";&&&&&&&&stt.setValue(100);&&&&&&&&try&{&&&&&&&&&&&&//&序列化&&&&&&&&&&&&byte[]&bb&=&simpleTypeCodec.encode(stt);&&&&&&&&&&&&//&反序列化&&&&&&&&&&&&SimpleTypeTest&newStt&=&simpleTypeCodec.decode(bb);&&&&&&&&}&catch&(IOException&e)&{&&&&&&&&&&&&e.printStackTrace();&&&&&&&&}嵌套对象的开发示例public&class&AddressBookProtosPOJO&{&&&&@Protobuf(fieldType&=&FieldType.OBJECT,&order=1,&required&=&false)&&&&public&Person&&&&&@Protobuf(fieldType&=&FieldType.OBJECT,&order=2,&required&=&false)&&&&public&List&Person&&}public&class&Person&{&&&&@Protobuf(fieldType&=&FieldType.STRING,&order=1,&required&=&true)&&&&public&String&&&&&@Protobuf(fieldType&=&FieldType.INT32,&order=2,&required&=&true)&&&&public&int&&&&&@Protobuf(fieldType&=&FieldType.STRING,&order=3,&required&=&false)&&&&public&String&&&&&@Protobuf(fieldType&=&FieldType.DOUBLE,&order=4,&required&=&false)&&&&public&Double&doubleF;&&&&@Protobuf(fieldType&=&FieldType.FLOAT,&order=5,&required&=&false)&&&&public&Float&floatF;&&&&@Protobuf(fieldType&=&FieldType.BYTES,&order=6,&required&=&false)&&&&public&byte[]&bytesF;&&&&@Protobuf(fieldType=FieldType.BOOL,&order=7,&required=false)&&&&public&Boolean&boolF;&&&&}&由注解对象动态生成Protobuf的IDL描述文件内容JProtobuf提供一个非常实用的功能,可以动态生成Protobuf的IDL描述文件内容//返回的内容即为&Protobuf的IDL描述文件String&code&=&ProtobufIDLGenerator.getIDL(SimpleTypeTest.class);public&class&SimpleTypeTest&{&&&&@Protobuf(fieldType&=&FieldType.STRING,&order&=&1,&required&=&true)&&&&private&String&&&&&@Protobuf(fieldType&=&FieldType.INT32,&order&=&2,&required&=&false)&&&&private&int&&&&&public&int&getValue()&{&&&&&&&&return&&&&&}&&&&public&void&setValue(int&value)&{&&&&&&&&this.value&=&&&&&}}&增加由.proto 描述文件动态生成Protobuf操作对象的支持JProtobuf提供一个更简单的功能,可支持动态Protobuf对象的生成功能,省去了注释的使用 基本使用示例如下:@Testpublic&void&testDecode()&throws&Exception&{&&&&//&通过&.proto描述文件生成动态解析对象&&&&String&protoCotent&=&"package&mypackage.&"&+&&&&&&&&&&&&"option&java_package&=&\"com.baidu.bjf.remoting.protobuf.simplestring\";"&+&&&&&&&&&&&&"option&java_outer_classname&=&\"StringTypeClass\";&&"&+&&&&&&&&&&&&"message&StringMessage&{&"&+&&&&&&&&&&&&"&&required&string&message&=&1;&}"&;&&&&IDLProxyObject&object&=&ProtobufIDLProxy.createSingle(protoCotent);&&&&//if&.proto&IDL&defines&multiple&messages&use&as&follow&&&&//Map&String,&IDLProxyObject&&objects&=&ProtobufIDLProxy.create(protoCotent);&&&&//&动态设置字段值&&&&object.put("message",&"hello你好");&&&&//propogation&object&set&&&&//object.put("sub.field",&"hello&world");&&&&//&protobuf&序列化&&&&byte[]&bb&=&object.encode();&&&&//&protobuf&反序列化&&&&IDLProxyObject&result&=&object.decode(bb);&&&&Assert.assertEquals("hello你好",&result.get("message"));&&&&//propogation&object&get&&&&//result.get("sub.field")}联系我们email:&
阅读(2696)
&re: jprotobuf 1.0.3发布,简化java程序员对google protobuf的应用
不错,谢谢分享&&&&
&re: jprotobuf 1.0.3发布,简化java程序员对google protobuf的应用
文章不错,支持一下,谢谢分享&&&&
&re: jprotobuf 1.0.3发布,简化java程序员对google protobuf的应用[未登录]
@Protobuf(fieldType = FieldType.STRING, order = 1, required = true)private S@Protobuf(fieldType = FieldType.INT32, order = 2, required = false)这些都可以用使用的默认值吧,如String =& STRING, int =& INT32, long =& INT64默认required = false, order按bean的field顺序这样别人就不需要写这么多东西了&&&&
&re: jprotobuf 1.0.3发布,简化java程序员对google protobuf的应用
@badqiu建议不错,后续会改进这一块,thx&&&&[摘要:远期正在做一柬埔寨的小,上线后正在运转过程当中,老是有效户反应运用正在收集要求时,速率较缓,影响用户体验。对该题目联合应用情况及代码举行剖析,发明存正在以下题目:
近期在做一柬埔寨的小项目,上线后在运行过程中,总是有用户反映应用在请求时,速度较慢,影响用户体验。对该问题结合使用环境及代码进行分析,发现存在以下问题:
App中使用Json进行数据传输,存在很多冗余字段的传输,而且经过查阅资料,Json对数据进行序列化以后,数据包仍然很大。
柬埔寨存在网络信号问题,很多情况下,信号较差,大数据包的传输存在压力
综合来说,网络环境不稳定和传输数据包过大应该是导致网络请求过程中吃力、或者是超时的主要原因,因此,在优化时,主要考虑如何压缩传输过程中数据包。
一、什么是Protobuf
protobuf,全称: Protocol Buffer,是Google开源的一种轻便高效的结构化数据格式,可以用于结构化数据的串行化,也称作序列化,主要用于数据存储或是RPC数据交换,支持多语言,可拓展
二、项目主页
protobuf主页:
protobuf下载():
protobuf Github:
因为环境下使用Java语言进行开发,因此我们选择Java版本进行下载。
首先需要到Protobuf主页上下载最新的源码包:下载地址
或者是下载Google打包好的下可:下载地址
3.1 源码编译
首先,在Eclipse中开发,需要引入protobuf需要的Jar包,而官方只给出了相应源码,因此需要自己进行编译。编译方法如下:
安装Maven环境,具体安装过程,参考网上:连接
安装好Maven后,需要进行编译,才能生成需要引入的Jar文件,具体操作为:首先将下载好的protoc.exe文件复制到\protobuf-2.6.1\src目录下。然后进入protobuf-2.6.1\java目录下,直接运行命令:
mvn install
编译完成后,会在\protobuf-2.6.1\java\target\目录下生成文件:protobuf-java-2.6.1.jar。可以直接导入Eclipse中进行使用
3.2 构建对象
即定义数据,需要新建一个文件,后缀名为.proto,例如,我需要生成对象如下:
public class ProductInfo
private String productID;
private String productN
private String productA
private String productD
需要按照以下步骤进行
新建文件,名为:ProductInfo.proto
使用UE或者NotePad++等编辑打开该文件,对需要录入的字段进行编辑,如下(UE直接写出来,太难排版了,只能上图)
说明:该文件中:
java_:包名
java_outer_classname:类名
ProductInfo:对象名
required:必须有值
optional:可以不写值
string:相当于Java中的String
int32:相当于Java中的int
具体proto文件类型、Java类型及C++类型对比如下:
具体还可以参考连接:
Protobuf语言指南
使用protoc进行编译,语句为:
protoc –java_out=E:\Android开源项目\Protobuf数据传输协议\protobuf ProductInfo.proto
protoc:指使用下载好的protoc.exe进行编译
java_out:编译时,生成的语言同样的参数也可以是cpp_out
“=” 后边内容为需要编译的文件路径和文件名
编译完成后,会在编译文件位置相同的路径下,生成编译完成的文件,Java的以包的形式存放,即以的形式存放。
至此,已经完成了Jar包的编译和需要传输的对象的编译,接下来举例说明如何进行使用。
3.3 在Java中使用
新建Android工程,将生成的Jar文件拷贝到工程目录下的libs文件夹里边,将生成的模型文件拷贝到工程中对应的包下边,可以进行创建和使用对象:
示例代码:
private void testProto()
ProductInfo.Product.Builder builder = ProductInfo.Product.newBuilder();
builder.setAmount("100");
builder.setUid(10010);
builder.setProductCode("Product1");
builder.setLuckNum("12345");
builder.setAllPhoneNum("10086");
// 生成product对象
ProductInfo.Product product = builder.build();
// 转换为Byte
byte[] products = product.toByteArray();
Product productParse = ProductInfo.Product.parseFrom(products);
catch (InvalidProtocolBufferException e)
e.printStackTrace();
至此,已经可以再Eclipse中使用ProtoBuf,这里只是介绍了使用办法,具体的性能测试和原理分析,待我研究下,再来写。
这里有我已经编译好的Jar包,可以直接使用:下载链接
【protobuf】 3.使用protobuf-csharp-port进行序列化和反序列化
初识序列化和反序列化,使用BinaryFormatter类、ISerializable、XmlSerializer类进行序列化和反序列化
序列化(串行化)- 使用BinaryFormatter进行序列化
使用JSON Serializer 进行序列化或反序列化时出错。的长度超过了为 maxJsonLength属性
使用XStream对Java对象进行序列化和反序列化
unity3d中使用proto对象进行序列化和反序列化
解决“使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错”的问题
在web环境中使用JAXB对XML文件进行序列化和反序列化时如何避免乱码
mvc “使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错,字符串的长度超过了为 maxJsonLength 属性设置的值”博客访问: 3213409
博文数量: 1037
博客积分: 12070
博客等级: 上将
技术积分: 11339
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
required string name = 1;
required int32 id = 2;&&&&&&& //
Unique ID number for this person.
optional string email = 3;
PhoneType {
MOBILE = 0;
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
repeated PhoneNumber phone = 4;
repeated Person person = 1;
required int32 msg_type = 1;
required int32 msg_size = 2;
boundMsg.ParseFromIstream(buf);
bo1.ParseFromIstream(bo1Buf);
bo2.ParseFromIstream(bo2Buf);
count = 0;
piece_size = net_read(fileBuf,1024);
write_file(filename,fileBuf,piece_size);
count = count + piece_
&0m35.414s
阅读(3336) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。Protobuf学习笔记(一)
Protobuf学习笔记(一)
数据结构描述语言
Protocol Buffer
Protobuf基础概念
Protobuf是google开发的数据结构描述语言,能够将结构化数据序列化与反序列化,取代json和xml,常用于服务器通信协议、RPC系统和数据持久化存储系统中。
优点:高性能,数据协议小,平台无关,语言无关,向前和向后兼容
缺点:通用性比XML差,以二进制存储,无法直接读取出protobuf的内容。
Protobuf在应用场景之一
客户端程序是使用Java开发的,可能运行自不同的平台,如:Linux、Windows或者是Android,而我们的服务器程序通常是基于Linux平台并使用C++开发完成的。在这两种程序之间进行数据通讯时存在多种方式用于设计消息格式。
Protobuf字段类型对应
Protobuf type
c++ type
protobuf &type &describe
ByteString
可包含任意顺序的字节数据。
使用可变长编码方式。编码负数时不够高效如果字段负数,那么使用sint32更高效
使用可变长编码方式。编码负数时不够高效如果字段含有负数,那么使用sint64。
使用可变长编码方式
使用可变长编码方式
使用可变长编码方式。有符号的整型值。编码时比通常的int32高效
使用可变长编码方式。有符号的整型值。编码时比通常的int64高效
总是4个字节。如果数值总是比2的28次方大的话,这个类型会比uint32高效
总是8个字节。如果数值总是比256大的话,这个类型会比uint64高效
总是4个字节
总是8个字节
一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本
Protobuf关键字说明
.proto语法
package:package_name
java_package
java_package:com.example.protobuf
java包路径声明
java-outer_classname
Java-outer_classname:classname
编译后生成的类名的声明
message MessageName{
required string name=1;
optional int32 id=2;
optional int32 age=3;
message消息定义关键字,编译后生成实体类,标签1,2,3在每个消息中必须是唯一的
该字段必须设置,且消息中至少有一个
该字段可以不设置值传递
该字段可不设置值,java中以List集合表示
service ServiceName{
rpc RpcName(MessageName)returns(MessageName){}
RPC服务定义
import&&path/other.proto&
引入其它的.proto文件
enum Corpus {
&&& UNIVERSAL = 0;
&&& WEB = 1;
&&& IMAGES = 2;
&&& LOCAL = 3;
&&& NEWS = 4;
表示可为字段指定某“预定义序列值”的一个值,来表示某一类型,如果为
enum修饰的字段指定预定义序列值之外的值,那么解析器就会把它当做未知的值来对待
Protobuf在Java中的使用
安装编译器:
到google官网下载编译器(最新版为2.6.1),解压安装编译器,也可在该官网查阅Protocol Buffer API帮助文档,目前只有C++、GO、Java、Python和C#的API,
编译.proto文件
&& a.安装完编译器后可直接在安装目录的Dos环境下编译或是用批处理方式,为了避免造成不必要的麻烦编译失败,而无法查看错误,建议用批处理方式:
proc&path_src=$src_path&java_out=$out_path&$path\filename.proto
将.proto编译成相应的.java文件
Protobuf各类字段在java中设值/取值方式
字段角色&&&
设值方式
取值方式
是否是必设值
有无默认值
getX(int&index)/getX()
Protobuf应用消息升级规则
1)& 原有标签号必须被保留,不能被新字段重用。
2)不能移除和添加required限定符字段。
3)新添加字段必须是optional和required限定符。
4)int32、uint32、int64、uint64和bool等类型之间是兼容的,sint32和sint64是兼容的,string和bytes是兼容的且必须是UTF-8编码,fixed32兼容sfixed32,以及fixed64兼容sfixed64,这意味着如果想修改原有字段的类型时,为了保证兼容性,只能将其修改为与其原有类型兼容的类型。
5)optional限定符兼容repeated限定符。
Protobuf和json对比
浏览器端ProtocolBufer和JSON序列化和反序列化对比
Protocol& Buffer
&&&&&&&&&& JSON
序列化所需时间(ms)
反序列化时间(ms)
所占空间(B)
序列化所需时间(ms)
反序列化时间(ms)
所占空间(B)
Java 服务端ProtocolBuffer和JSON序列化和反序列化对比
ProtocolBuffer
序列化所需时间
反序列化时间
序列化所需时间
反序列化时间
Protobuf数据类型编码性能对比
序列化数值
序列化次数
序列化所需时间
序列化后编码长度
序列化数值
序列化次数
序列化所需时间
序列化后编码长度
序列化数值
序列化次数
序列化所需时间
序列化后编码长度
表1,对负值进行序列化
表2,对正直序列化,且该&#3647大于2的28次方
表3,对正直序列化,且该&#728小于2的28次方
我的热门文章
即使是一小步也想与你分享是因为把线性结构恢复为树状结构的复杂度和直接使用线性结构相同么?
我的理解是,PB可以使用一个键值对的repetead字段模拟Map,也就没有必要在语言层面上做。
3.0里已经支持了,就是还没release
3.0里已经支持了,就是还没release
ProtoBuf 3.0 pre-release已经支持了:&br&&a href=&///?target=https%3A///google/protobuf/releases/tag/v3.0.0-alpha-2& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Release Protocol Buffers v3.0.0-alpha-2 · google/protobuf · GitHub&i class=&icon-external&&&/i&&/a&
ProtoBuf 3.0 pre-release已经支持了:
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 protobuf反序列化 的文章

 

随机推荐