5

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 をスローしていたことが判明しました。メッセージが示すように、送信されるバイト数が多すぎます (この場合は、パディングを参照していました)。

SerializeToArrayこのパディングは、固定長バッファーでC++ の protobuf 関数を使用することで発生します。これを解消するために、次の一時的なコードを使用しました。

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 でファイルを開くときにどれだけ読むべきかを把握できるようにします。

4

2 に答える 2

4

Python 文字列には任意の文字を含めることができます。つまり、「バイナリ」データを直接保持できます。文字列から「バイナリ」に変換する必要はありません。

于 2009-12-07T14:27:08.513 に答える
4

私は Python の専門家ではありませんが、新しい文字列型などを作成しなくても、file.read()操作の結果を に渡すことができます。message.ParseFromString(...)

于 2009-12-07T14:23:20.033 に答える