Как прочитать двоичные данные protobuf C++ с помощью protobuf Python?
-
13-09-2019 - |
Вопрос
Версия Google protobuf для Python дает нам только:
SerializeAsString()
Версия C++ дает нам оба:
SerializeToArray(...)
SerializeAsString()
Мы записываем данные в наш файл C++ в двоичном формате и хотели бы сохранить его в таком виде.Тем не менее, есть ли способ прочитать двоичные данные в Python и проанализировать их, как если бы это была строка?
Это правильный способ сделать это?
binary = get_binary_data()
binary_size = get_binary_size()
string = None
for i in range(len(binary_size)):
string += i
message = new MyMessage()
message.ParseFromString(string)
Обновлять:
Вот новый пример и проблема:
message_length = 512
file = open('foobars.bin', 'rb')
eof = False
while not eof:
data = file.read(message_length)
eof = not data
if not eof:
foo_bar = FooBar()
foo_bar.ParseFromString(data)
Когда мы доберемся до foo_bar.ParseFromString(data)
строку, я получаю эту ошибку:
Exception Type: DecodeError
Exception Value: Too many bytes when decoding varint.
Обновление 2:
Оказывается, заполнение двоичных данных отбрасывало protobuf;было отправлено слишком много байтов, как следует из сообщения (в данном случае речь шла о заполнении).
Это заполнение происходит за счет использования функции protobuf C++, SerializeToArray
в буфере фиксированной длины.Чтобы устранить это, я использовал этот временный код:
message_length = 512
file = open('foobars.bin', 'rb')
eof = False
while not eof:
data = file.read(message_length)
eof = not data
string = ''
for i in range(0, len(data)):
byte = data[i]
if byte != '\xcc': # yuck!
string += data[i]
if not eof:
foo_bar = FooBar()
foo_bar.ParseFromString(string)
Я думаю, здесь есть конструктивный недостаток.Я повторно реализую свой код C++ так, чтобы он записывал массивы переменной длины в двоичный файл.Как указано в документации protobuf, я буду добавлять к каждому сообщению его двоичный размер, чтобы знать, сколько читать, когда я открываю файл с помощью Python.
Решение
Я не эксперт в Python, но вы можете передать результат file.read()
операция в message.ParseFromString(...)
без необходимости создавать новый тип строки или что-то еще.
Другие советы
Строки Python могут содержать любые символы, т.е.они способны напрямую хранить «двоичные» данные.Не должно быть необходимости конвертировать строку в «двоичный».