如何使用Python protobuf读取二进制C ++ protobuf数据?

时间:2009-12-07 14:07:06

标签: c++ python protocol-buffers

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 个答案:

答案 0 :(得分:4)

我不是Python专家,但您可以将file.read()操作的结果传递给message.ParseFromString(...),而无需构建新的字符串类型或任何内容。

答案 1 :(得分:4)

Python字符串可以包含任何字符,即它们能够直接保存“二进制”数据。应该不需要从字符串转换为“二进制”。