كيف يمكنني قراءة بيانات Protobuf الثنائية C ++ باستخدام Python Protobuf؟

StackOverflow https://stackoverflow.com/questions/1860187

  •  13-09-2019
  •  | 
  •  

سؤال

يعطينا نسخة Python من Google Protobuf فقط:

SerializeAsString()

حيث يعطينا نسخة C ++ كلاهما:

SerializeToArray(...)
SerializeAsString()

نكتب إلى ملف C ++ لدينا بتنسيق ثنائي، ونود أن نحتفظ به بهذه الطريقة. ومع ذلك، هل هناك طريقة لقراءة البيانات الثنائية في بيثون وتحليلها كما لو كانت سلسلة؟

هل هذه هي الطريقة الصحيحة للقيام بذلك؟

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 على المخزن المؤقت بطول ثابت. للقضاء على هذا، استخدمت هذا الرمز Temproary:

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.

هل كانت مفيدة؟

المحلول

أنا لست خبيرا مع بيثون، لكن يمكنك تمرير نتيجة file.read() عملية message.ParseFromString(...) دون الحاجة إلى بناء نوع سلسلة جديدة أو أي شيء.

نصائح أخرى

يمكن أن تحتوي سلاسل بيثون على أي شخصية، أي أنها قادرة على عقد بيانات "ثنائية" مباشرة. يجب ألا تكون هناك حاجة للتحويل من سلسلة إلى "ثنائية".

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top