Глава 15 · Python и файлы

Бинарные файлы и переносы строк

Не всё, что лежит в файле, — текст. И даже текст занимает на диске больше, чем кажется.

Бинарный режим

Добавьте b к режиму, чтобы работать с файлом как с чистыми байтами, без какой-либо текстовой кодировки:

binarny_fajl.py
data = bytes([0, 1, 2, 3, 255])

with open("signal.bin", "wb") as f:
    f.write(data)

with open("signal.bin", "rb") as f:
    print(f.read())   # b'\\x00\\x01\\x02\\x03\\xff'
РежимЧто получаем в PythonПример
"rt" / "r"str (текст)"Python"
"rb"bytes (двоичные данные)b'Python'
Не декодируйте произвольные бинарные данные как текст
PNG, JPEG или PDF не станут читаемыми от open(..., encoding="utf-8") — это не текстовые данные, и попытка прочитать их как текст приведёт к ошибке или мусору. Для таких форматов используйте бинарный режим ("rb") или специализированную библиотеку для этого формата.
Debug Lab 9: Бинарные данные, прочитанные как текст
bin_kak_text.py
data = bytes([0, 1, 2, 3, 255])
with open("signal.bin", "wb") as f:
    f.write(data)

with open("signal.bin", "r", encoding="utf-8") as f:
    print(f.read())
Traceback (most recent call last):
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 4: invalid start byte
Что видно на экране

Байт 0xff не образует корректный символ в UTF-8 — эти данные никогда и не были текстом. Файл нужно открывать в бинарном режиме ("rb"), а не текстовом.

Исправленный код
bin_pravilno.py
with open("signal.bin", "rb") as f:
    print(f.read())   # b'\\x00\\x01\\x02\\x03\\xff'

Переносы строк и текстовый режим

\n внутри Python — универсальный перевод строки
На разных операционных системах исторически применяются разные последовательности для перевода строки на диске (например, \r\n в файлах, созданных на Windows). Текстовый режим Python читает такие файлы в режиме универсальных переносов строк и отдаёт вам во всех случаях \n — вам не нужно обрабатывать оба варианта вручную в обычном текстовом коде.

Символы против байтов — реальный пример

simvoly_vs_bajty.py
text = "Питон🐍"
print(len(text))                  # 6 — количество символов
print(len(text.encode("utf-8")))  # 14 — количество байт в UTF-8
Длина текста ≠ размер файла в байтах
Кириллица и эмодзи занимают в UTF-8 несколько байт на один символ. len(text) считает символы, а не байты — размер файла на диске может быть заметно больше, чем количество символов в строке.
Практика: бинарные файлы и переносы строк
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →