На этом шаге мы рассмотрим способы решения этой задачи.
Вам нужно прочесть или записать бинарные данные, такие как содержимое картинок, звуковых файлов и т. п.
Используйте функцию open() в режиме rb или wb, чтобы читать и записывать бинарные данные. Например:
# Прочесть весь файл как одну байтовую строку with open('somefile.bin', 'rb') as f: data = f.read() # Записать бинарные данные в файл with open('somefile.bin', 'wb') as f: f.write(b'Hello World')
При чтении бинарных данных важно подчеркнуть, что все получаемые данные будут в форме байтовых, а не текстовых строк. Похожим образом при записи вы
должны предоставить данные в форме объектов, которые представляют данные в форме байтов (байтовые строки, объекты bytearray и т. д.).
При чтении бинарных данных тонкие сематические различия между байтовыми и текстовыми строками могут привести к проблемам. Нужно помнить, что индексирование и итерирование возвращают целочисленное байтовое значение, а не байтовые строки. Например:
>>> t = 'Hello World' >>> t[0] 'H' >>> for c in t: print(c) H e l l o W o r l d >>> >>> # Байтовая строка >>> b = b'Hello World' >>> b[0] 72 >>> for c in b: print(c) 72 101 108 108 111 32 87 111 114 108 100 >>>
Если вам когда-либо потребуется прочесть текст из или записать в открытый в бинарном режиме файл, убедитесь, что не забыли декодировать или закодировать его. Например:
with open('somefile.bin', 'rb') as f: data = f.read(16) text = data.decode('utf-8') with open('somefile.bin', 'wb') as f: text = 'Hello World' f.write(text.encode('utf-8'))
Менее известный аспект бинарного ввода-вывода заключается в том, что такие объекты, как массивы и структуры языка C, могут быть использованы для записи без какого-либо промежуточного преобразования в объект bytes. Например:
import array nums = array.array('i', [1, 2, 3, 4]) with open('data.bin', 'wb') as f: f.write(nums)
Это применимо к любому объекту, в котором реализован так называемый "буферный интерфейс", который напрямую дает доступ к собственному буферу памяти операциям, которые могут с ним работать. Запись бинарных данных - одна из таких операций.
Многие объекты также позволяют бинарным данным напрямую быть прочитанными в их память с помощью файлового метода readinto(). Например:
>>> import array >>> a = array.array('i', [0, 0, 0, 0, 0, 0, 0, 0]) >>> with open('data.bin', 'rb') as f: f.readinto(a) 16 >>> a array('i', [1, 2, 3, 4, 0, 0, 0, 0]) >>>
Однако нужно принять все меры предосторожности при использовании этого приема, поскольку он часто является платформозависимым и зависит от таких вещей, как размер слова, порядок следования байтов (big-endian или little- endian).
На следующем шаге мы рассмотрим запись в файл, которого еще нет.