Читать и интерпретировать смешанный двоичный и текстовый файл в python

Как я могу прочитать файл, состоящий из строки (строка из 10 csv) чисел и текста, а затем после этой строки 4096 байт?

Что-то вроде этого:

  117,47966,55,115,223,224,94,0,28,OK: 
  \00\00\00\F6\FF\EF\FFF\00\FA\FF\00\CA\FF\009\00Z\00\D9\FFF\00\E3\FF?\00\F0\FF\00\B1\FF\9D\FF\00:\00b\00\E9\FF*\00:\00\00)\00\D3\FF,\00\C6\FF\D6\FF2\00\00!\00\00\00\FE\FF\BA\FF[\00\E8\FF.\00\F7\FF\F9\FF\E6\FF\00\D3\FF\F8\FF\00&\00\

Раньше я использовал ConstBitStream для чтения чистых двоичных файлов. Мне было интересно, как я могу читать построчно, и каждый раз, когда я нахожу «ОК:», использовать ConstBitStream для чтения следующих 4096 байтов?

with open(filename, encoding="latin-1") as f:
        lines = f.readlines()
        for i in range(1,len(lines)):
            elements = lines[i].strip().split(',')
            if(len(elements)==10):
                readNext4096bytes()

person rebrid    schedule 20.08.2019    source источник


Ответы (2)


Дайте мне знать, если это работает:

import pandas as pd
from bitstring import ConstBitStream

# Read csv using pandas
df = pd.read_csv(filename, error_bad_lines=False, encoding='latin1')

# Take the last column (10) and cast every value to ConstBitStream
df.iloc[:, 9].apply(ConstBitStream)
person Laurens Koppenol    schedule 20.08.2019
comment
Я получаю следующую ошибку: ParserError: Error tokenizing data. C error: Expected 1 fields in line 31, saw 2 Должен сказать, что в файле много строк, которые неверны. В своей попытке я действительно отфильтровывал только строки с точным количеством полей, а также проверял, что последняя на самом деле была «ОК:» - person rebrid; 20.08.2019
comment
Теперь он пропускает много строк, что может быть правильно, но затем он останавливается на ParserError: Error tokenizing data. C error: Buffer overflow caught - possible malformed input file. - person rebrid; 20.08.2019
comment
@brid что произойдет, если вы добавите nrows=10 как kwarg к pd.read_csv() - person Laurens Koppenol; 20.08.2019

Скажи, что твой файл такой

    1,2,3,OK:
    4096 bytes
    5,6,7,OK:
    4096 bytes
    ...
  1. прочитать файл в двоичном режиме: file = open(file_name, 'rb').read()
  2. split: data = file.split(b',OK:\n')
    data — это список: [b'1,2,3', b'4096bytes\n4,5,6', b'4096bytes\n7,8,9', ..., b'4096bytes']
  3. для типичного элемента это bitarray, record = element[:4096], element[4096+1:]
    вы, конечно, должны использовать особый случай для первого и последнего элемента...

PS если ваш файл состоит из ОДНОЙ записи и ОДНОГО битового массива, то data это просто
[b'1,2,3', b'4096bytes']

PPS, если ваша двоичная строка содержит b',OK:\n', описанный выше метод не работает, но — Возможные комбинации из 5 байтов — 256**5, количество последовательностей из 5 байтов в 4096 байтах — 4096+1-5, следовательно, вероятность этой неудачной возможности — 4092/256**5 → 3.7216523196548223e-09 * в одном двоичная запись * — если у вас есть несколько записей, это вероятно нормально, если у вас несколько миллионов записей, вам нужно много памяти, но вероятность ошибки больше не пренебрежимо мало.

person gboffi    schedule 20.08.2019
comment
Это действительно несколько записей. Я получаю эту ошибку, хотя ValueError: Must have exactly one of create/read/write/append mode and at most one plus в функции открытия - person rebrid; 20.08.2019
comment
Ой, это open(..., 'rb') . Я отредактировал ответ. - person gboffi; 20.08.2019
comment
Хорошо, теперь он читает это правильно. Какой самый быстрый способ сохранить каждую запись в другом массиве? Теперь они в одном списке и он возвращает IOPub data rate exceeded. The notebook server will temporarily stop sending output to the client in order to avoid crashing it. To change this limit, set the config variable --NotebookApp.iopub_data_rate_limit. Current values: NotebookApp.iopub_data_rate_limit=1000000.0 (bytes/sec) NotebookApp.rate_limit_window=3.0 (secs) - person rebrid; 20.08.2019
comment
У меня нет ни ваших файлов, ни вашей комбинации аппаратного и программного обеспечения, поэтому я не могу вам больше помочь. - person gboffi; 20.08.2019