protobuf 嵌入的消息导致额外的字节,这是分隔符吗?
protobuf embedded message leads to extra bytes, is this delimeter?
我正在尝试 protobuf->python 的示例代码,我有 pytest.proto
message Person{
required string name=1;
required int32 id=2;
optional string email=3;
enum PhoneType{
mobile=0;
home=1;
work=2;
}
message PhoneNumber{
required string number=1;
optional PhoneType type=2[default=home];
}
repeated PhoneNumber phone=4;
}
编译它
protoc pytest.proty --python_out=./
然后是我的 python 文件:
import pytest_pb2
import sys
person=pytest_pb2.Person()
person.name="bbb"
person.id=9
phone_number=person.phone.add()
phone_number.number="aaa"
phone_number.type=pytest_pb2.Person.work
f=open("log4py.data","w")
s=person.SerializeToString()
f.write(s)
f.close()
运行它:
$python pytest.py && xxd log4py.data
00000000: 0a03 6262 6210 0922 070a 0361 6161 1002 ..bbb.."...aaa..
name="bbb" id=9 ??? number="aaa" type=home
从上面我可以看到
0a03 6262 62 --> name="bbb"
1009 --> id=9
22 07 --> What's this??????????????????
0a03 616 161 --> number="aaa"
1002 --> type=home
没看懂这里多出来的“22 07”是什么意思,好像是嵌入结构?所以我将 python 程序更改为有 2 个 "phone_number" 实例,如下所示:
phone_number1=person.phone.add()
phone_number1.number="aaa"
phone_number1.type=pytest_pb2.Person.work
phone_number2=person.phone.add()
phone_number2.number="ccc"
phone_number2.type=pytest_pb2.Person.work
运行 它和我得到:
$python pytest.py && xxd log4py.data
00000000: 0a03 6262 6210 0922 070a 0361 6161 1002 ..bbb.."...aaa..
00000010: 2207 0a03 6363 6310 02 "...ccc..
嗯,这一次,我在每个 PhoneNumber 实例之前看到两次“22 07”。我知道 Protobuf 不对任何分隔符字节进行编码,但这里似乎“22 07”是分隔符。有什么解释吗?
字节是sub-message的标签和长度。
22
是一个标签。后三位 (2) 表示后面的字段值是 length-delimited 值。高5位(4)表示这是字段号4,也就是phone
字段。
07
是长度。 sub-message 是 7 个字节长。
I knew that Protobuf doesn't encode any delimeter bytes
不正确:Sub-messages 必须以某种方式分隔。 Protobuf 更喜欢使用长度前缀而不是特殊的结束标记来定界,因为它允许您跳过字段而不解码每个字节。
我正在尝试 protobuf->python 的示例代码,我有 pytest.proto
message Person{
required string name=1;
required int32 id=2;
optional string email=3;
enum PhoneType{
mobile=0;
home=1;
work=2;
}
message PhoneNumber{
required string number=1;
optional PhoneType type=2[default=home];
}
repeated PhoneNumber phone=4;
}
编译它
protoc pytest.proty --python_out=./
然后是我的 python 文件:
import pytest_pb2
import sys
person=pytest_pb2.Person()
person.name="bbb"
person.id=9
phone_number=person.phone.add()
phone_number.number="aaa"
phone_number.type=pytest_pb2.Person.work
f=open("log4py.data","w")
s=person.SerializeToString()
f.write(s)
f.close()
运行它:
$python pytest.py && xxd log4py.data
00000000: 0a03 6262 6210 0922 070a 0361 6161 1002 ..bbb.."...aaa..
name="bbb" id=9 ??? number="aaa" type=home
从上面我可以看到
0a03 6262 62 --> name="bbb"
1009 --> id=9
22 07 --> What's this??????????????????
0a03 616 161 --> number="aaa"
1002 --> type=home
没看懂这里多出来的“22 07”是什么意思,好像是嵌入结构?所以我将 python 程序更改为有 2 个 "phone_number" 实例,如下所示:
phone_number1=person.phone.add()
phone_number1.number="aaa"
phone_number1.type=pytest_pb2.Person.work
phone_number2=person.phone.add()
phone_number2.number="ccc"
phone_number2.type=pytest_pb2.Person.work
运行 它和我得到:
$python pytest.py && xxd log4py.data
00000000: 0a03 6262 6210 0922 070a 0361 6161 1002 ..bbb.."...aaa..
00000010: 2207 0a03 6363 6310 02 "...ccc..
嗯,这一次,我在每个 PhoneNumber 实例之前看到两次“22 07”。我知道 Protobuf 不对任何分隔符字节进行编码,但这里似乎“22 07”是分隔符。有什么解释吗?
字节是sub-message的标签和长度。
22
是一个标签。后三位 (2) 表示后面的字段值是 length-delimited 值。高5位(4)表示这是字段号4,也就是phone
字段。
07
是长度。 sub-message 是 7 个字节长。
I knew that Protobuf doesn't encode any delimeter bytes
不正确:Sub-messages 必须以某种方式分隔。 Protobuf 更喜欢使用长度前缀而不是特殊的结束标记来定界,因为它允许您跳过字段而不解码每个字节。