Если вы включите символ 'b' в строку
У нас под рукой нет бинарного стихотворения, поэтому мы просто сгенерируем 256 байтовых значений от 0 до 255:
>>> bdata = bytes(range(0, 256))
>>> len(bdata)
256
Откроем файл для записи в бинарном режиме и запишем все данные сразу:
>>> fout = open('bfile', 'wb')
>>> fout.write(bdata)
256
>>> fout.close()
И вновь функция write() возвращает количество записанных байтов.
Как и в случае с текстом, вы можете записывать бинарные данные фрагментами:
>>> fout = open('bfile', 'wb')
>>> size = len(bdata)
>>> offset = 0
>>> chunk = 100
>>> while True:
…·····if offset > size:
…··········break
…·····fout.write(bdata[offset: offset+chunk])
…·····offset += chunk
…
100
100
56
>>> fout.close()
Читаем бинарные файлы с помощью функции read()
Это просто: все, что вам нужно, — открыть файл в режиме 'rb':
>>> fin = open('bfile', 'rb')
>>> bdata = fin.read()
>>> len(bdata)
256
>>> fin.close()
Закрываем файлы автоматически с помощью ключевого слова with
Если вы забудете закрыть за собой файл, его закроет Python после того, как будет удалена последняя ссылка на него. Это означает, что, если вы откроете файл и не закроете его явно, он будет закрыт автоматически по завершении функции. Но вы можете открыть файл внутри длинной функции или даже основного раздела программы. Файл должен быть закрыт, чтобы все оставшиеся операции записи были завершены.
У Python имеются
>>> with open('relativity', 'wt') as fout:
…·····fout.write(poem)
…
Вот и все. После того как блок кода, расположенный под менеджером контекста (в этом случае одна строка), завершится (или нормально, или путем генерации исключения), файл будет закрыт автоматически.
Меняем позицию с помощью функции seek()
По мере чтения и записи Python отслеживает ваше местоположение в файле. Функция tell() возвращает ваше текущее смещение от начала файла в байтах. Функция seek() позволяет вам перейти к другому смещению в файле. Это значит, что вам не обязательно читать каждый байт файла, чтобы добраться до последнего, — вы можете использовать функцию seek(), чтобы сместиться к последнему байту и считать его.
Для примера воспользуемся 256-байтным бинарным файлом 'bfile', который мы создали ранее:
>>> fin = open('bfile', 'rb')
>>> fin.tell()
0
Используем функцию seek(), чтобы перейти к предпоследнему байту файла:
>>> fin.seek(255)
255
Считаем все данные от текущей позиции до конца файла:
>>> bdata = fin.read()
>>> len(bdata)
1
>>> bdata[0]
255
Функция seek() также возвращает текущее смещение.
Вы также можете вызвать функцию seek(), передав ей второй аргумент: seek(
• если значение origin равно 0 (по умолчанию), сместиться на
• если значение origin равно 1, сместиться на
• если значение origin равно 2, сместиться на
Эти значения также определены в стандартном модуле os:
>>> import os
>>> os.SEEK_SET
0
>>> os.SEEK_CUR
1
>>> os.SEEK_END
2
Благодаря этому мы можем считать последний байт разными способами:
>>> fin = open('bfile', 'rb')
Один байт перед концом файла:
>>> fin.seek(-1, 2)
255
>>> fin.tell()
255
Считать данные до конца файла:
>>> bdata = fin.read()
>>> len(bdata)
1
>>> bdata[0]
255
Вам не нужно вызывать функцию tell(), чтобы работала функция seek(). Я только хотел показать, что обе эти функции возвращают одинаковое смещение.
Рассмотрим случай, когда мы вызываем функцию seek(), чтобы сместиться с текущей позиции:
>>> fin = open('bfile', 'rb')
Следующий пример переносит позицию за 2 байта до конца файла:
>>> fin.seek(254, 0)
254
>>> fin.tell()
254
Теперь перейдем вперед на 1 байт: