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

Я прочитал большой файл в коде ниже, который имеет специальную структуру – среди прочего, два блока, которые нужно обрабатывать одновременно. Вместо того, чтобы искать назад и вперед в файле, я загружаю эти два блока, завернутые в вызовы 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 для этого раздела, и вы можете продолжить фрагмент, чтобы оставить остаток для следующего цикла.

Interesting Posts

Многомерное многочленное деление в шалфе

получить индексы исходного текста из nltk word_tokenize

Python: сохранение данных с помощью поплавков и строк с помощью np.savetxt

Сельдерей Получил незарегистрированную задачу типа (пример)

Python: передача нескольких LARGE-последовательностей через hmmlearn

Ошибка SQL-запроса через mysqldb.query в Python

В Python heapq.heapify не принимает cmp или ключевые функции в качестве аргументов, как отсортировано

Использование подпроцесса модуля с тайм-аутом

Использование Lambda и кортежей для отправки нескольким функциям: Python, Tkinter

Ошибка H14 в героике – «нет запущенных веб-процессов»

Передача данных между классами в Tweepy и Tornado WebSocket

Как использовать список Python для назначения std :: vector в C ++ с помощью SWIG?

Как узнать / изменить текущий каталог в оболочке Python?

Scrapy – как идентифицировать уже очищенные URL-адреса

Проблемы с OpenGL-модулем PyQt5 и управление версиями (вызывает неправильные _QOpenGLFunctions_ (ver))

Python - лучший язык программирования в мире.