Чтение двоичного файла с памятью

Я прочитал большой файл в коде ниже, который имеет специальную структуру – среди прочего, два блока, которые нужно обрабатывать одновременно. Вместо того, чтобы искать назад и вперед в файле, я загружаю эти два блока, завернутые в вызовы memoryview

 with open(abs_path, 'rb') as bsa_file: # ... # load the file record block to parse later file_records_block = memoryview(bsa_file.read(file_records_block_size)) # load the file names block file_names_block = memoryview(bsa_file.read(total_file_name_length)) # close the file file_records_index = names_record_index = 0 for folder_record in folder_records: name_size = struct.unpack_from('B', file_records_block, file_records_index)[0] # discard null terminator below folder_path = struct.unpack_from('%ds' % (name_size - 1), file_records_block, file_records_index + 1)[0] file_records_index += name_size + 1 for __ in xrange(folder_record.files_count): file_name_len = 0 for b in file_names_block[names_record_index:]: if b != '\x00': file_name_len += 1 else: break file_name = unicode(struct.unpack_from('%ds' % file_name_len, file_names_block,names_record_index)[0]) names_record_index += file_name_len + 1 

Файл правильно разобран, но поскольку это мое первое использование интерфейса mamoryview, я не уверен, что делаю это правильно. Файл_names_block состоит из невидимых строк c.

  1. Является ли мой трюк file_names_block[names_record_index:] с использованием магии памяти или создаю некоторые n ^ 2 среза? Нужно ли использовать здесь islice ?
  2. Как видно, я просто ищу нулевой байт вручную, а затем unpack_from к unpack_from . Но я прочитал в разделе Как разбить строку байта на отдельные байты в python, что я могу использовать cast() (docs?) В представлении памяти – каким-либо образом использовать этот (или другой трюк) для разделения вида в байтах? Могу ли я просто вызвать split('\x00') ? Это сохранит эффективность памяти?

Я хотел бы получить представление об одном правильном способе сделать это (в python 2).

One Solution collect form web for “Чтение двоичного файла с памятью”

memoryview не даст вам никаких преимуществ, когда дело доходит до строк с нулевым завершением, поскольку у них нет возможностей ни для чего, кроме данных фиксированной ширины. Вы можете также использовать здесь bytes.split() :

 file_names_block = bsa_file.read(total_file_name_length) file_names = file_names_block.split(b'\00') 

Нарезка memoryview не использует дополнительную память (кроме параметров представления), но если вы используете приведение, вы создаете новые собственные объекты для области анализируемой памяти в тот момент, когда вы пытаетесь получить доступ к элементам в последовательности.

Вы все еще можете использовать memoryview для синтаксического анализа file_records_block ; эти строки имеют префикс длины, давая вам возможность использовать нарезку. Просто продолжайте нарезать байты представления памяти при обработке параметров folder_path , нет необходимости хранить индекс:

 for folder_record in folder_records: name_size = file_records_block[0] # first byte is the length, indexing gives the integer folder_path = file_records_block[1:name_size].tobytes() file_records_block = file_records_block[name_size + 1:] # skip the null 

Поскольку memoryview была получена из объекта с bytes , индексирование даст вам целочисленное значение для байта, .tobytes() на данном срезе дает вам новую строку bytes для этого раздела, и вы можете продолжить фрагмент, чтобы оставить остаток для следующего цикла.

  • Список блокировок
  • Pythonic способ получить возвращаемое значение функции в соответствующих единицах
  • Pandas: SettingWithCopyWarning
  • Можете ли вы легко создать подобный списку объект в python, который использует что-то вроде дескриптора для своих элементов?
  • Пип висит в Windows 7
  • Импортировать библиотеку Python из Github
  • Могу ли я опустить файлы .pyo и .pyc в RPM?
  • UnboundLocalError: локальная переменная ... ссылка перед назначением
  • Анаконда Python 32-бит пытается загрузить 64-битные библиотеки Anaconda
  • Регулярное выражение для включения и исключения определенных IP-адресов
  • функция python, которая возвращает переменное количество выходов
  • Python - лучший язык программирования в мире.