Разделите чрезвычайно длинный поток байтов на меньшие байты - PullRequest
0 голосов
/ 02 марта 2019

Так что мне нужно распаковать чрезвычайно длинный поток байтов (от USB) в 4-байтовые значения.

В настоящее время у меня все работает, но я чувствую, что есть лучший способ сделать это.

В настоящее время я получил:

l=[]
for i in range(int(len(mybytes)/4)):
    l.append(struct.unpack_from('>i',mybytes,i*4))

Так что это кажется очень дорогим ресурсом, и я делаю это для 16k байтов много.

Я также чувствую, что это, вероятно, спросили, прежде чем я простодействительно не знаю, как произнести это слово для поиска

Ответы [ 3 ]

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

Вы также можете попробовать модуль массива, который может загружаться напрямую из двоичных данных:

 import array
 arr = array.array("I",mybytes) # "I" stands for unsigned integer
 arr.byteswap() # only if you're reading endian coding different from your platform
 l = list(arr)
0 голосов
/ 02 марта 2019

Вы можете указать размер распакованных целых чисел (Python 3.6 +):

>>> import struct
>>> mybytes = bytes([1,2,3,4,5,6,7,8])
>>> struct.unpack(f'>2i',mybytes)
(16909060, 84281096)
>>> n = len(mybytes) // 4
>>> struct.unpack(f'>{n}i',mybytes) # Python 3.6+ f-strings
(16909060, 84281096)
>>> struct.unpack('>{}i'.format(n),mybytes) # Older Pythons
(16909060, 84281096)
>>> [hex(i) for i in _]
['0x1020304', '0x5060708']
0 голосов
/ 02 марта 2019

Оберните его в BytesIO объект, затем используйте iter для вызова его read метода, пока он не вернёт пустое значение bytes.

>>> import io, struct
>>> bio = io.BytesIO(b'abcdefgh')
>>> int_fmt = struct.Struct(">i")
>>> list(map(int_fmt.unpack, iter(lambda: bio.read(4), b'')))
[(1633837924,), (1701209960,)]

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

>>> bio = io.BytesIO(b'abcdefgh')
>>> list(map(lambda i: int.from_bytes(i, 'big'), iter(lambda: bio.read(4), b'')))
[1633837924, 1701209960]
...