Я читаю в двоичном файле (jpg в этом случае), и потребность найти некоторые значения в том файле. Для заинтересованных, двоичный файл является jpg, и я пытаюсь выбрать его размеры путем поиска двоичной структуры, как детализировано здесь.
Я должен найти FFC0 в двоичных данных, перескочить некоторое число байтов и затем считать 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, вам нужно будет исправить на одну вещь меньше.
Модуль битовой строки был разработан примерно для этой цели. В вашем случае следующий код (который я не тестировал) должен помочь проиллюстрировать:
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))
Модуль re
работает как со строковыми , так и с двоичными данными ( str
в Python 2 и байта
в Python 3), поэтому вы можете использовать его вместе с str.find
для своей задачи.
Ну, очевидно, есть PIL Модуль Image имеет размер в качестве атрибута. Если вы хотите получить размер именно так, как вы предлагаете, и без загрузки файла, вам придется пройтись по нему строка за строкой. Это не самый приятный способ, но он работает.