如何用Python protobuf读取二进制C++ protobuf数据?
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出错;发送的字节太多了,正如消息所提示的那样(在这种情况下是指填充)。
这个填充是因为在固定长度的缓冲区上使用了C++ protobuf函数 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打开文件时就知道该读取多少数据。
2 个回答
4
Python中的字符串可以包含任何字符,也就是说,它们可以直接存储“二进制”数据。你不需要把字符串转换成“二进制”。
4
我对Python不是很精通,但你可以直接把file.read()
操作得到的结果放进message.ParseFromString(...)
里,不需要再创建什么新的字符串类型或者其他东西。