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

Posted

技术标签:

【中文标题】如何使用 Python protobuf 读取二进制 C++ protobuf 数据?【英文标题】:How do I read binary C++ protobuf data using Python protobuf? 【发布时间】:2009-12-07 14:07:06 【问题描述】:

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 打开文件时知道要读取多少内容。

【问题讨论】:

我不太确定你想用你的循环做什么,但你会用它提出一个TypeError。您将None 分配给名称string,然后尝试向其添加一系列ints。在 python 中,字符串是一个字节序列,因此任何二进制数据在字符串中都应该是安全的。您能否更清楚地解释 SerializeAsString 对您的数据做错了什么? 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

【讨论】:

这对 Python 3 来说不再适用了。

以上是关于如何使用 Python protobuf 读取二进制 C++ protobuf 数据?的主要内容,如果未能解决你的问题,请参考以下文章

用于解析包含数组格式的 protobuf 数据的二进制文件的 Python API

使用 C# 中的 ProtoBuf-Net 库将类数据保存到加密文件

通过 Google Protobuf 发送二进制文件数据

在python中如何从二进制文件中读取信息

Protobuf编码

如何解码二进制/原始谷歌 protobuf 数据