Comment puis-je lire les données protobuf C ++ binaires en utilisant protobuf Python?
-
13-09-2019 - |
Question
La version Python de Google protobuf nous donne seulement:
SerializeAsString()
Où que la version C ++ nous donne à la fois:
SerializeToArray(...)
SerializeAsString()
Nous écrivons à notre fichier C ++ au format binaire, et nous aimerions le garder ainsi. Cela dit, est-il un moyen de lecture des données binaires en Python et l'analyse comme si elle était une chaîne?
Est-ce la bonne façon de le faire?
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)
Mise à jour:
Voici un nouvel exemple, et un problème:
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)
Quand nous arrivons à la ligne foo_bar.ParseFromString(data)
, je reçois cette erreur:
Exception Type: DecodeError
Exception Value: Too many bytes when decoding varint.
Mise à jour 2:
Il se trouve que le rembourrage sur les données binaires vomissait protobuf off; trop d'octets ont été envoyés, comme le message suggère (dans ce cas, il faisait référence au rembourrage).
Ce rembourrage est d'utiliser la fonction C protobuf de, SerializeToArray
sur un tampon de longueur fixe. Pour éliminer cela, je l'ai utilisé ce code 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)
Il y a un défaut de conception ici, je pense. Je réimplémenter mon code C ++ afin qu'il écrit des tableaux de longueur variable dans le fichier binaire. Comme indiqué par la documentation protobuf, je préfixer chaque message avec sa taille binaire pour que je sache combien lire quand j'ouvrir le fichier avec Python.
La solution
Je ne suis pas un expert en Python, mais vous pouvez passer le résultat d'une opération de file.read()
en message.ParseFromString(...)
sans avoir à construire un nouveau type de chaîne ou quoi que ce soit.
Autres conseils
chaînes de Python peuvent contenir des caractères, à savoir qu'ils sont capables de contenir des données « binaires » directement. Il ne devrait pas être nécessaire de convertir chaîne en « binaire ».