Python 3.6 - Разделение шестнадцатеричных данных - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь прочитать двоичный файл и получить заголовок в формате utf-8. Однако остальная часть файла имеет байтовые значения, превышающие десятичную 127, поэтому я не могу преобразовать это в строку. Я должен разделить текст до; (или 0x3B), и я не могу заставить его работать.

with open("test_qifs_single_frame.qifs", "rb") as file:
    data = file.read()

print(binascii.hexlify(data))

Я также не могу прочитать это как строку, потому что это говорит мне, что я не могу декодировать 0x81 в UTF-8. Что я понимаю, это выходит за пределы диапазона ASCII. Что я могу сделать, чтобы решить эту проблему?

1 Ответ

0 голосов
/ 03 марта 2019

Вы можете читать файл побайтно, пока не достигнете символа остановки, а затем декодировать прочитанные данные.

Создать некоторые данные образца

>>> from random import randint
>>> header = 'Heaðer;'.encode('utf-8')
>>> bs = b''.join(bytes.fromhex('{:0>2x}'.format(randint(0, 255))) for _ in range(56))
>>> with open('test_qifs_single_frame.qifs', 'wb') as f:
...     f.write(header + bs)
>>>

Считать заголовок из файла

>>> # Create a bytearray to hold the bytes that we read.
>>> ba = bytearray()

>>> import functools
>>> with open('test_qifs_single_frame.qifs', 'rb') as f:
...     breader = functools.partial(f.read, 1)
...     for b in iter(breader, b';'):
...         ba += b
... 
>>> ba
bytearray(b'Hea\xc3\xb0er')
>>> ba.decode('utf-8')
'Heaðer'

Если встроенному iter передано вызываемое и значение, оно будет вызывать вызываемое до тех пор, пока не вернет значение. В коде мы используем functools.partial , чтобы создать функцию, которая читает файл по одному байту за раз, а затем передает его в iter.

...