官网地址
学习protocol协议写入二进制格式。
简单的案例
message Test1 {
optional int32 a = 1;
}
protocol编码格式为TLK,tag-length-value,其中length为可选的。tag描述字段序号,与字段类型。tag为1-15占用一个byte,其中byte后三位为字段类型,前面为字段序号。
message Test1 {
optional int32 a = 1;
}
public class Test1Main {
public static void main(String[] args) {
Test1.Builder builder = Test1.newBuilder().setA(150);
Test1 build = builder.build();
byte[] bytes = build.toByteArray();
System.out.println("build:" + build);
for (int i = 0; i < bytes.length; i++) {
System.out.println("i :" + i + ",== " + Arrays.toString(CommonUtils.getBitArray(bytes[i])));
}
}
}
i :0,== [0, 0, 0, 0, 1, 0, 0, 0]//字段序号为8(8位后移动3位为1,对应序号为1),类型为0
i :1,== [1, 0, 0, 1, 0, 1, 1, 0]
i :2,== [0, 0, 0, 0, 0, 0, 0, 1]
tag大于等于16占用两个byte,其中byte后三位为字段类型,前面为字段序号。
option java_multiple_files = true;
message Test2 {
optional int32 a = 300;
}
public class Test2Main {
public static void main(String[] args) {
Test2.Builder builder = Test2.newBuilder().setA(150);
Test2 build = builder.build();
byte[] bytes = build.toByteArray();
System.out.println("build:" + build);
for (int i = 0; i < bytes.length; i++) {
System.out.println("i :" + i + ",== " + Arrays.toString(CommonUtils.getBitArray(bytes[i])));
}
}
}
i :0,== [1, 1, 1, 0, 0, 0, 0, 0]
i :1,== [0, 0, 0, 1, 0, 0, 1, 0]
//0, 0, 1, 0, 0, 1, 0 ++ 1, 1, 0, 0, 0, 0, 0
//=2048 + 256 + 64 + 32 = 2400 tag 2400(1400位后移动3位为300,对应序号为300) ,类型为0
i :2,== [1, 0, 0, 1, 0, 1, 1, 0]
i :3,== [0, 0, 0, 0, 0, 0, 0, 1]
消息类型
消息类型有以下几类。
| Type | Meaning | Used For |
|---|---|---|
| 0 | Varint | int32, int64, uint32, uint64, sint32, sint64, bool, enum |
| 1 | 64-bit | fixed64, sfixed64, double |
| 2 | Length-delimited | string, bytes, embedded messages, packed repeated fields |
| 3 | Start group | groups (deprecated) |
| 4 | End group | groups (deprecated) |
| 5 | 32-bit | fixed32, sfixed32, float |
Varints编码
每个字节第一位代表后面是否还有数据,为0则没有,1则有。每个字节只有7个bit存储数据。
- 案例数值 = 1
0000 0001
- 案例数值 = 300
1010 1100 0000 0010
1010 1100 0000 0010
→ 010 1100 000 0010
000 0010 010 1100
→ 000 0010 ++ 010 1100
→ 100101100
→ 256 + 32 + 8 + 4 = 300
ZigZag编码
ZigZag将有符号数,映射成无符号数。
| Signed Original | Encoded As |
|---|---|
| 0 | 0 |
| -1 | 1 |
| 1 | 2 |
| -2 | 3 |
| 2147483647 | 4294967294 |
| -2147483648 | 4294967295 |
(n << 1) ^ (n >> 31)
(n << 1) ^ (n >> 63)
String类型
String类型,l会有值,为byte长度。
message Test2 {
optional string b = 2;
}
- string值为 testing
12 07 [74 65 73 74 69 6e 67]
对象类型
对象类型,l会有值,为byte长度。
message Test3 {
optional Test1 c = 3;
}
1a 03 08 96 01