чтение двоичных данных побайтно и извлечение данных с использованием Python - PullRequest
0 голосов
/ 26 июня 2018

У меня есть файл, содержимое которого ниже:

 0:   10 51 03 37 7F 43 82 99  45 3F E7 35 3A A8 80 B9   .text ? etc  # text 
10:   3D 3F F4 49 F8 9A 7A 85  03 40 8A C8 46 DE 0A 1A   . -@ =! ETC  # text 
30:   .......................................................
40:   ...........................................10 03

     Repeat next instant 
     10 51 ................................................................
     ............................................ 10 03

Это сообщение, где 10 и 51 показывают начало определенного сообщения, а 10 03 - конец сообщения.10 обозначает позицию 0 байтов, 51 обозначает позицию 1 байта и продолжает.

Моя цель - прочитать шестнадцатеричные данные 5-8-байтовой позиции и преобразовать их в число с плавающей запятой и 9-16 байтов в удвоение для каждого момента времени

Моя реализация до сих пор читает только первые 31 шестнадцатеричные данные.

 import struct

with open("RawData.log",'rb') as fin:
    data1 = ["{:02x}".format(ord(c)) for c in fin.read()]
    data2=''.join(data1)

    #data=pd.DataFrame({'test':data1})
    header = "51"
    tail   = "03"


   # header_index = data2.index(header)
    header_index=[i for i, s in enumerate(data1) if header in s]
    footer_index = [i for i, s in enumerate(data1) if tail  in s]
    if header_index >= 0 and footer_index >= header_index:
       body = data2[10:18]
       print struct.unpack('!f',body.decode('hex'))[0]

       #261.197418213 only 1 output not iterating for whole file. Similarly how to extract 9 to 16 byte position data to double for entire file.

Как прочитать весь файл и извлечь только те 2 поля из шестнадцатеричных данных для каждого найденного заголовка сообщения (10 и 51)

1 Ответ

0 голосов
/ 27 июня 2018

Это простой способ извлечения данных между разделителями и распаковки с плавающей запятой и двойного от первых 12 позиций каждого сообщения в файле:

with open('RawData.log', 'rb') as f:  # read data in binary format
    bs = f.read()
prev = None
start = None
end = None
for i, b in enumerate(bs):
    if prev == b'\x10' and b == b'\x51':
        # match beginning of message
        start = i + 1 
    if prev == b'\x10' and b == b'\x03':
        # match end of message
        end = i - 1 
    if start and end:
        data = bs[start:end]
        fmt = '!fd'   # unpack a float and double, big-endian
        flt, dble = struct.unpack(fmt, data[:12])
        print flt, dble
        # reset delimiter positions
        start = None
        end = None
    prev = b 
...