2017-01-13 1 views
2

я пытался образец кода protobuf-> питона, у меня есть pytest.protoВведенное сообщение protobuf приводит к дополнительным байтам, является ли этот делиметр?

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=./ 

Тогда мой файл питон:

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» означает, здесь, кажется, указывает, что есть вложенная структура? Поэтому я изменил свою программу питона, чтобы иметь 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.. 

Ну, на этот раз, я вижу "22 07" дважды, перед каждым экземпляром PhoneNumber. Я знал, что Protobuf не кодирует никаких байтов деления, но здесь кажется, что «22 07» являются метриками. Любые объяснения?

ответ

2

Байт - это тег и длина под-сообщения.

22 является тегом. Нижние три бита (2) указывают, что следующее значение поля представляет собой значение с разделителем длины. Верхние 5 бит (4) указывают, что это поле номер 4, которое является полем phone.

07 - длина. Под-сообщение длиной 7 байтов.

Я знал, что Protobuf не кодирует любые разделители байтов

Не верно: Суб-сообщения должны быть разделены каким-то образом. Протобуф предпочитает ограничивать использование префикса длины, а не специального конечного тега, потому что он позволяет пропустить поле без декодирования каждого байта.

Смежные вопросы