读书人

java编码与protobuf运用

发布时间: 2013-08-16 14:29:57 作者: rapoo

java编码与protobuf使用

OutputStreamWriter 转换字符到字节,同样 StreamEncoder 类负责将字符编码成字节,编码格式和默认编码规则与解码是一致的。
?2>内存操作

? ? ? String s = "字符串。。。";

? ? ? byte[] bt = s.getBytes("UTF-8");

? ? ? String str = new String(bt,"UTF-8");

?? ? ?String 类就提供转换到字节的方法,也支持将字节转换为字符串的构造函数。

Charset 提供 encode 与 decode 分别对应 char[] 到 byte[] 的编码和 byte[] 到 char[] 的解码。如下代码所示:


?

d、使用protoc命令进行编译


java编码与protobuf运用
?

2>序列化和反序列化分析

1、package与optionjava_package同时存在,后者会取代前者 。

java代码生成相关参考:https://developers.google.com/protocol-buffers/docs/reference/java-generated?hl=zh-CN

2、PB数据类型

? required: a well-formed message must have exactly one of this field.

? optional: a well-formed message can have zero or one of this field (but not more than one).

? repeated: this field can be repeated any number of times (including zero) in a well-formed message. ? ? ? ? ? ? ? ? ? ?The order of the repeated values will be preserved.

类型参考https://developers.google.com/protocol-buffers/docs/proto?hl=zh-CN&csw=1

3、message的编码特点

? ? ? ? ?PB之所以解析速度快、所占体积小,很大程度上是由它序列化的编码特点来决定的。

3.1 Base 128 Varints

? ? ? ? PB采用了Base 128 Varints来变长编码整数:

? ? 变长编码的整数,它可能包含多个byte,对于每个byte的8位,其中后7位表示数值,最高的一位表示是否还有还有另一个byte,0表示没有,1表示有;

越前面的byte表示数值的低位,越后面的byte表示数值的高位;

?

例子:
300 ??varints? 编码为:1010 1100 0000 0010

解释如下:
300的2进制编码为:0001 0010 1100
按照刚才的规则,高低位颠倒,截取最后的7为放在第一个byte,则第一byte为1010 1100(其中最高位1表示,后续还有byte);接着剩下的内容放到第二个byte,为0000 0010(其中最高位0表示,后续无byte,这个数到这里截止了)。
于是,合在一起为 1010 1100 0000 0010;

PB将 key编码成下面的结构:?

X?YYYY?ZZZ
其中:最高位X表示是否还有后续的byte来编码数字别名;YYYY用于编码别名,定义了多于16个属性,则需要用到额外的byte,所以出现频率高的字段应当取1-16的别名);ZZZ表示这个字段的类型,PB支持的属性的对应规则如下表:

java编码与protobuf运用
?3.2具体实例分析

如下图所示,针对上述定义的proto文件及序列化后的字节流进行分析


java编码与protobuf运用
? ? ? ? ? ? ? byte[0]: ?10 ? ? ? ? ??0 0001 010 别名1,类型repeated

? ? ? ? ? ? ??byte[1]: ?14 ? ? ? ? ?一个对象所占字节数

? ? ? ? ? ? ??byte[2]: ?8 ? ? ? ? ? 0?0001 000 missionId

? ? ? ? ? ? ? byte[3]: ?16 ? ? ? ? 0 0010 000 missionUserId

? ? ? ? ? ? ??byte[4]: ?24 ? ? ? ? 0 0011 000 status

? ? ? ? ? ? ??byte[5]: ?32 ? ? ? ? 0 0100 000 finishedTime

? ? ? ? PB具有跨平台、解析速度快、序列化数据体积小、扩展性高、使用简单的特点。但是我们也可以看到,相比于XML,PB的数据,并不是自然可读的;同时它生成的代码不是纯pojo,对于代码有一定的侵入性。例如pb不支持像Map<Long, 0bject>,其中Object会出现多种不确定的类型,这样就无法通过pb序列化。从上述分析的数据可以看出,protobuf采用的k-v存储结构,并且采用变长的字节编码格式,所以从空间效率比较高。

读书人网 >编程

热点推荐