Поиск/чтение двоичных данных в Python

Я читаю в двоичном файле (jpg в этом случае), и потребность найти некоторые значения в том файле. Для заинтересованных, двоичный файл является jpg, и я пытаюсь выбрать его размеры путем поиска двоичной структуры, как детализировано здесь.

Я должен найти FFC0 в двоичных данных, перескочить некоторое число байтов и затем считать 4 байта (это должно дать мне размеры изображения).

Что такое хороший способ искать значение в двоичных данных? Существует ли эквивалент 'находки' или чего-то как ре?

22
задан jww 16 October 2018 в 01:44
поделиться

4 ответа

Фактически вы можете загрузить файл в строку и найти в этой строке последовательность байтов 0xffc0 , используя метод str.find () . Работает для любой последовательности байтов.

Код для этого зависит от пары вещей. Если вы открываете файл в двоичном режиме и используете Python 3 (оба из которых, вероятно, являются лучшей практикой для этого сценария), вам нужно будет искать строку байтов (в отличие от строки символов), что означает, что вы перед строкой должен стоять b .

with open(filename, 'rb') as f:
    s = f.read()
s.find(b'\xff\xc0')

Если вы откроете файл в текстовом режиме в Python 3, вам придется искать строку символов:

with open(filename, 'r') as f:
    s = f.read()
s.find('\xff\xc0')

, хотя для этого нет особой причины. Это не дает вам никаких преимуществ по сравнению с предыдущим способом, и если вы работаете на платформе, которая обрабатывает двоичные файлы и текстовые файлы по-разному (например, Windows), есть вероятность, что это вызовет проблемы.

Python 2 не делает различий между байтовыми и символьными строками, поэтому, если вы используете эту версию, не имеет значения, включаете ли вы b в b или исключаете его. '\ xff \ xc0' . И если ваша платформа обрабатывает двоичные файлы и текстовые файлы одинаково (например, Mac или Linux), не имеет значения, используете ли вы 'r' или 'rb' в качестве файлового режима либо . Но я бы по-прежнему рекомендовал использовать что-то вроде первого примера кода, приведенного выше, только для прямой совместимости - если вы когда-нибудь переключитесь на Python 3, вам нужно будет исправить на одну вещь меньше.

13
ответ дан 29 November 2019 в 05:13
поделиться

Модуль битовой строки был разработан примерно для этой цели. В вашем случае следующий код (который я не тестировал) должен помочь проиллюстрировать:

from bitstring import ConstBitStream
# Can initialise from files, bytes, etc.
s = ConstBitStream(filename='your_file')
# Search to Start of Frame 0 code on byte boundary
found = s.find('0xffc0', bytealigned=True)
if found:
    print("Found start code at byte offset %d." % found[0])
    s0f0, length, bitdepth, height, width = s.readlist('hex:16, uint:16, 
                                                        uint:8, 2*uint:16')
    print("Width %d, Height %d" % (width, height))
6
ответ дан 29 November 2019 в 05:13
поделиться

Модуль re работает как со строковыми , так и с двоичными данными ( str в Python 2 и байта в Python 3), поэтому вы можете использовать его вместе с str.find для своей задачи.

4
ответ дан 29 November 2019 в 05:13
поделиться

Ну, очевидно, есть PIL Модуль Image имеет размер в качестве атрибута. Если вы хотите получить размер именно так, как вы предлагаете, и без загрузки файла, вам придется пройтись по нему строка за строкой. Это не самый приятный способ, но он работает.

2
ответ дан 29 November 2019 в 05:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: