io.md
1> **Источник:** https://python-all.ru/3.4/library/io.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 16.2. [`io`](https://python-all.ru/3.4/library/io.html#module-io) – Основные инструменты для работы с потоками89## 16.2.1. Обзор1011Модуль [`io`](https://python-all.ru/3.4/library/io.html#module-io) предоставляет основные средства Python для работы с различными типами ввода-вывода. Существует три основных типа ввода-вывода: *текстовый ввод-вывод*, *двоичный ввод-вывод* и *сырой ввод-вывод*. Это общие категории, и для каждой из них могут использоваться различные хранилища данных. Конкретный объект, принадлежащий к любой из этих категорий, называется [*файловым объектом*](https://python-all.ru/3.4/glossary.html#term-file-object). Другие распространённые термины – *поток* и *объект, подобный файлу*.1213Независимо от категории, каждый конкретный объект потока также может обладать различными возможностями: он может быть только для чтения, только для записи или для чтения и записи. Он также может поддерживать произвольный доступ (переход вперёд или назад к любому месту) или только последовательный доступ (например, в случае сокета или канала).1415Все потоки внимательны к типу данных, которые им передаются. Например, передача объекта [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) методу `write()` двоичного потока вызовет исключение `TypeError`. То же самое произойдёт при передаче объекта [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) методу `write()` текстового потока.1617Изменено в версии 3.3: Операции, которые раньше вызывали [`IOError`](https://python-all.ru/3.4/library/exceptions.html#IOError), теперь вызывают [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError), поскольку [`IOError`](https://python-all.ru/3.4/library/exceptions.html#IOError) теперь является псевдонимом [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError).1819### 16.2.1.1. Текстовый ввод/вывод2021Текстовый ввод-вывод ожидает и создаёт объекты [`str`](https://python-all.ru/3.4/library/stdtypes.html#str). Это означает, что когда хранилище данных изначально состоит из байтов (как в случае с файлом), кодирование и декодирование данных выполняется прозрачно, а также выполняется опциональное преобразование символов новой строки, специфичных для платформы.2223Самый простой способ создать текстовый поток – использовать [`open()`](https://python-all.ru/3.4/library/functions.html#open), опционально указав кодировку:2425```python26f = open("myfile.txt", "r", encoding="utf-8")27```2829Текстовые потоки в памяти также доступны как объекты [`StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO):3031```python32f = io.StringIO("some initial text data")33```3435API текстовых потоков подробно описан в документации [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase).3637### 16.2.1.2. Двоичный ввод/вывод3839Двоичный ввод-вывод (также называемый *буферизованным вводом-выводом*) ожидает и создаёт объекты [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes). Никакого кодирования, декодирования или преобразования новых строк не выполняется. Эта категория потоков может использоваться для всех видов нетекстовых данных, а также когда требуется ручное управление обработкой текстовых данных.4041Самый простой способ создать двоичный поток – использовать [`open()`](https://python-all.ru/3.4/library/functions.html#open) с `'b'` в строке режима:4243```python44f = open("myfile.jpg", "rb")45```4647Двоичные потоки в памяти также доступны как объекты [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO):4849```python50f = io.BytesIO(b"some initial binary data: \x00\x01")51```5253API двоичных потоков подробно описан в документации [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase).5455Другие модули библиотеки могут предоставлять дополнительные способы создания текстовых или двоичных потоков. Смотрите, например, [`socket.socket.makefile()`](https://python-all.ru/3.4/library/socket.html#socket.socket.makefile).5657### 16.2.1.3. Сырой ввод/вывод5859Необработанный ввод-вывод (также называемый *небуферизованным вводом-выводом*) обычно используется как низкоуровневый строительный блок для двоичных и текстовых потоков; редко бывает полезно напрямую манипулировать необработанным потоком из пользовательского кода. Тем не менее, можно создать необработанный поток, открыв файл в двоичном режиме с отключённой буферизацией:6061```python62f = open("myfile.jpg", "rb", buffering=0)63```6465API сырых потоков подробно описан в документации [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase).6667## 16.2.2. Интерфейс модуля высокого уровня6869#### `io.DEFAULT_BUFFER_SIZE`7071Целое число, содержащее размер буфера по умолчанию, используемый буферизованными классами ввода-вывода модуля. [`open()`](https://python-all.ru/3.4/library/functions.html#open) использует blksize файла (получаемый с помощью [`os.stat()`](https://python-all.ru/3.4/library/os.html#os.stat)), если это возможно.7273#### `io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)`7475Это псевдоним для встроенной функции [`open()`](https://python-all.ru/3.4/library/functions.html#open).7677#### `exception io.BlockingIOError`7879Это псевдоним для совместимости со встроенным исключением [`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError).8081#### `exception io.UnsupportedOperation`8283Исключение, наследующее [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError) и [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError), которое вызывается при попытке выполнить неподдерживаемую операцию над потоком.8485### 16.2.2.1. Потоки в памяти8687Также можно использовать объект, подобный [`str`](https://python-all.ru/3.4/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes), в качестве файла как для чтения, так и для записи. Для строк [`StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO) можно использовать как файл, открытый в текстовом режиме. [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO) можно использовать как файл, открытый в двоичном режиме. Оба предоставляют полные возможности чтения и записи с произвольным доступом.8889> **См. также**90>91> **[`sys`](https://python-all.ru/3.4/library/sys.html#module-sys)**92>93> содержит стандартные потоки ввода-вывода:94>95> [`sys.stdin`](https://python-all.ru/3.4/library/sys.html#sys.stdin)96>97> ,98>99> [`sys.stdout`](https://python-all.ru/3.4/library/sys.html#sys.stdout)100>101> и102>103> [`sys.stderr`](https://python-all.ru/3.4/library/sys.html#sys.stderr)104>105> .106107## 16.2.3. Иерархия классов108109Реализация потоков ввода-вывода организована в виде иерархии классов. Сначала [*абстрактные базовые классы*](https://python-all.ru/3.4/glossary.html#term-abstract-base-class) (ABC), которые используются для определения различных категорий потоков, затем конкретные классы, предоставляющие стандартные реализации потоков.110111> > **Примечание**112> >113> > Абстрактные базовые классы также предоставляют реализации некоторых методов по умолчанию, чтобы облегчить реализацию конкретных классов потоков. Например, [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) предоставляет неоптимизированные реализации `readinto()` и [`readline()`](https://python-all.ru/3.4/library/io.html#io.IOBase.readline).114115На вершине иерархии ввода-вывода находится абстрактный базовый класс [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase). Он определяет базовый интерфейс для потока. Однако обратите внимание, что нет разделения между чтением и записью в потоках; реализациям разрешено вызывать [`UnsupportedOperation`](https://python-all.ru/3.4/library/io.html#io.UnsupportedOperation), если они не поддерживают данную операцию.116117Абстрактный базовый класс [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) расширяет [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase). Он занимается чтением и записью байтов в поток. [`FileIO`](https://python-all.ru/3.4/library/io.html#io.FileIO) является подклассом [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) и предоставляет интерфейс для файлов в файловой системе машины.118119Абстрактный базовый класс [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) занимается буферизацией на сыром байтовом потоке ([`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase)). Его подклассы [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter), [`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader) и [`BufferedRWPair`](https://python-all.ru/3.4/library/io.html#io.BufferedRWPair) буферизуют потоки, которые доступны для чтения, записи или для чтения и записи одновременно. [`BufferedRandom`](https://python-all.ru/3.4/library/io.html#io.BufferedRandom) предоставляет буферизованный интерфейс для потоков с произвольным доступом. Ещё один подкласс [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase), [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO), представляет собой поток байтов в памяти.120121Абстрактный базовый класс [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase), ещё один подкласс [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase), занимается потоками, байты которых представляют текст, и обрабатывает кодирование и декодирование в строки и из строк. [`TextIOWrapper`](https://python-all.ru/3.4/library/io.html#io.TextIOWrapper), который расширяет его, представляет собой буферизованный текстовый интерфейс к буферизованному сырому потоку ([`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase)). Наконец, [`StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO) – это поток текста в памяти.122123Имена аргументов не являются частью спецификации, и только аргументы [`open()`](https://python-all.ru/3.4/library/functions.html#open) предназначены для использования в качестве именованных аргументов.124125В следующей таблице приведены ABC, предоставляемые модулем [`io`](https://python-all.ru/3.4/library/io.html#module-io):126127| ABC | Наследует | Методы-заглушки | Методы-примеси и свойства |128| --- | --- | --- | --- |129| [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) | | `fileno`, `seek`, и `truncate` | `close`, `closed`, `__enter__`, `__exit__`, `flush`, `isatty`, `__iter__`, `__next__`, `readable`, `readline`, `readlines`, `seekable`, `tell`, `writable` и `writelines` |130| [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) | [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) | `readinto` и `write` | Унаследованные методы [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase), `read`, и `readall` |131| [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) | [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) | `detach`, `read`, `read1` и `write` | Унаследованные методы [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase), `readinto` |132| [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase) | [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) | `detach`, `read`, `readline` и `write` | Унаследованные методы [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase), `encoding`, `errors` и `newlines` |133134### 16.2.3.1. Базовые классы ввода/вывода135136#### `class io.IOBase`137138Абстрактный базовый класс для всех классов ввода-вывода, работающий с потоками байтов. Отсутствует открытый конструктор.139140Этот класс предоставляет пустые абстрактные реализации для многих методов, которые производные классы могут выборочно переопределять; реализации по умолчанию представляют файл, который нельзя читать, записывать или позиционировать.141142Хотя [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) не объявляет `read()`, `readinto()`, или `write()`, поскольку их сигнатуры различаются, реализации и клиенты должны считать эти методы частью интерфейса. Кроме того, реализации могут вызывать [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError) (или [`UnsupportedOperation`](https://python-all.ru/3.4/library/io.html#io.UnsupportedOperation)) при вызове неподдерживаемых операций.143144Основным типом для двоичных данных, читаемых из файла или записываемых в файл, является [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes). [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray) также принимаются, а в некоторых случаях (например, для `readinto()`) требуются. Классы текстового ввода-вывода работают с данными типа [`str`](https://python-all.ru/3.4/library/stdtypes.html#str).145146Обратите внимание, что вызов любого метода (даже запросов) для закрытого потока не определён. Реализации могут вызывать [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError) в этом случае.147148[`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) (и его подклассы) поддерживает протокол итератора, то есть объект [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) можно итерировать, получая строки потока. Строки определяются несколько по-разному в зависимости от того, является ли поток двоичным (возвращает байты) или текстовым (возвращает строки). См. [`readline()`](https://python-all.ru/3.4/library/io.html#io.IOBase.readline) ниже.149150[`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) также является менеджером контекста и поэтому поддерживает оператор [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with). В этом примере *file* закрывается после завершения блока оператора [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with), даже если возникает исключение:151152```python153with open('spam.txt', 'w') as file:154 file.write('Spam and eggs!')155```156157[`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) предоставляет следующие атрибуты данных и методы:158159#### `close()`160161Сбрасывает буфер и закрывает этот поток. Этот метод не делает ничего, если файл уже закрыт. Как только файл закрыт, любая операция с файлом (например, чтение или запись) вызовет [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError).162163Для удобства допускается вызывать этот метод несколько раз; однако эффект будет иметь только первый вызов.164165#### `closed`166167`True`, если поток закрыт.168169#### `fileno()`170171Возвращает базовый файловый дескриптор (целое число) потока, если он существует. Если объект ввода-вывода не использует файловый дескриптор, вызывается [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError).172173#### `flush()`174175Сбрасывает буферы записи потока, если это применимо. Для потоков только для чтения и неблокирующих потоков эта операция ничего не делает.176177#### `isatty()`178179Возвращает `True`, если поток интерактивный (т.е. подключен к терминалу/tty-устройству).180181#### `readable()`182183Возвращает `True`, если из потока можно читать. Если `False`, `read()` возбудит [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError).184185#### `readline(size=-1)`186187Читает и возвращает одну строку из потока. Если указан *size*, будет прочитано не более *size* байт.188189Терминатором строки для бинарных файлов всегда является `b'\n'`; для текстовых файлов аргумент *newline* функции [`open()`](https://python-all.ru/3.4/library/functions.html#open) можно использовать для выбора распознаваемого(ых) терминатора(ов) строки.190191#### `readlines(hint=-1)`192193Читает и возвращает список строк из потока. Можно указать *hint* для ограничения количества читаемых строк: чтение прекратится, когда общий размер (в байтах/символах) всех прочитанных строк превысит *hint*.194195Обратите внимание, что по файловым объектам уже можно итерироваться с помощью `for line in file: ...` без вызова `file.readlines()`.196197#### `seek(offset[, whence])`198199Изменяет позицию в потоке на указанное количество байт *offset*. *offset* интерпретируется относительно позиции, заданной *whence*. Значение по умолчанию для *whence* – `SEEK_SET`. Допустимые значения для *whence*:200201- `SEEK_SET` или `0` – начало потока (по умолчанию); *offset* должен быть нулевым или положительным202- `SEEK_CUR` или `1` – текущая позиция в потоке; *offset* может быть отрицательным203- `SEEK_END` или `2` – конец потока; *offset* обычно отрицательный204205Возвращает новую абсолютную позицию.206207Новое в версии 3.1: Константы `SEEK_*`.208209Новое в версии 3.3: Некоторые операционные системы могут поддерживать дополнительные значения, например `os.SEEK_HOLE` или `os.SEEK_DATA`. Допустимые значения для файла могут зависеть от того, открыт ли он в текстовом или бинарном режиме.210211#### `seekable()`212213Возвращает `True`, если поток поддерживает произвольный доступ. Если `False`, [`seek()`](https://python-all.ru/3.4/library/io.html#io.IOBase.seek), [`tell()`](https://python-all.ru/3.4/library/io.html#io.IOBase.tell) и [`truncate()`](https://python-all.ru/3.4/library/io.html#io.IOBase.truncate) возбудят [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError).214215#### `tell()`216217Возвращает текущую позицию в потоке.218219#### `truncate(size=None)`220221Изменяет размер потока до указанного *size* в байтах (или до текущей позиции, если *size* не указан). Текущая позиция в потоке не изменяется. Это изменение размера может увеличить или уменьшить текущий размер файла. В случае увеличения содержимое новой области файла зависит от платформы (в большинстве систем дополнительные байты заполняются нулями, в Windows они не определены). Возвращается новый размер файла.222223#### `writable()`224225Return `True` if the stream supports writing. If `False`, `write()` and [`truncate()`](https://python-all.ru/3.4/library/io.html#io.IOBase.truncate) will raise [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError).226227#### `writelines(lines)`228229Записывает список строк в поток. Разделители строк не добавляются, поэтому обычно каждая переданная строка уже содержит разделитель в конце.230231#### `__del__()`232233Подготовка к уничтожению объекта. [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) предоставляет реализацию этого метода по умолчанию, которая вызывает метод [`close()`](https://python-all.ru/3.4/library/io.html#io.IOBase.close) экземпляра.234235#### `class io.RawIOBase`236237Базовый класс для необработанного бинарного ввода-вывода. Наследует [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase). Открытого конструктора нет.238239Необработанный двоичный ввод-вывод обычно предоставляет низкоуровневый доступ к базовому устройству или API операционной системы и не пытается инкапсулировать его в высокоуровневые примитивы (это оставлено буферизованному и текстовому вводу-выводу, описанным далее на этой странице).240241В дополнение к атрибутам и методам из [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase), [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) предоставляет следующие методы:242243#### `read(size=-1)`244245Читает до *size* байт из объекта и возвращает их. Для удобства, если *size* не указан или равен -1, вызывается [`readall()`](https://python-all.ru/3.4/library/io.html#io.RawIOBase.readall). В противном случае выполняется только один системный вызов. Может быть возвращено меньше *size* байт, если системный вызов вернул меньше *size* байт.246247Если возвращено 0 байт, а *size* не был равен 0, это означает конец файла. Если объект находится в неблокирующем режиме и байты недоступны, возвращается `None`.248249#### `readall()`250251Читает и возвращает все байты из потока до EOF, при необходимости выполняя несколько вызовов к потоку.252253#### `readinto(b)`254255Читает до `len(b)` байт в [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray) *b* и возвращает количество прочитанных байт. Если объект находится в неблокирующем режиме и байты недоступны, возвращается `None`.256257#### `write(b)`258259Записывает заданный объект [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) или [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray), *b*, в нижележащий небуферизованный поток и возвращает количество записанных байт. Оно может быть меньше `len(b)` в зависимости от особенностей нижележащего небуферизованного потока, особенно если он находится в неблокирующем режиме. `None` возвращается, если небуферизованный поток настроен не блокироваться и ни один байт не может быть сразу записан в него.260261#### `class io.BufferedIOBase`262263Базовый класс для двоичных потоков, поддерживающих некоторую буферизацию. Он наследует [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase). Открытый конструктор отсутствует.264265Основное отличие от [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) заключается в том, что методы [`read()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.read), [`readinto()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.readinto) и [`write()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.write) будут пытаться (соответственно) прочитать столько входных данных, сколько запрошено, или потребить все переданные выходные данные, ценой, возможно, более одного системного вызова.266267Кроме того, эти методы могут вызывать [`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError), если нижележащий небуферизованный поток находится в неблокирующем режиме и не может принять или отдать достаточно данных; в отличие от их аналогов из [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase), они никогда не вернут `None`.268269Besides, the [`read()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.read) method does not have a default implementation that defers to [`readinto()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.readinto).270271Типичная реализация [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) не должна наследовать от реализации [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase), а должна оборачивать её, как это делают [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter) и [`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader).272273[`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) предоставляет или переопределяет следующие методы и атрибуты в дополнение к тем, что есть в [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase):274275#### `raw`276277Нижележащий небуферизованный поток (экземпляр [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase)), с которым работает [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase). Это не часть API [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) и может отсутствовать в некоторых реализациях.278279#### `detach()`280281Отделяет базовый сырой поток от буфера и возвращает его.282283После отсоединения сырого потока буфер переходит в нерабочее состояние.284285Некоторые буферы, такие как [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO), не имеют понятия единого небуферизованного потока для возврата из этого метода. Они вызывают [`UnsupportedOperation`](https://python-all.ru/3.4/library/io.html#io.UnsupportedOperation).286287Новое в версии 3.1.288289#### `read(size=-1)`290291Читает и возвращает до *size* байт. Если аргумент опущен, равен `None` или отрицателен, данные читаются и возвращаются до достижения EOF. Пустой объект [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) возвращается, если поток уже находится в конце файла.292293Если аргумент положителен, а базовый сырой поток не является интерактивным, может быть выполнено несколько сырых чтений, чтобы обеспечить требуемое количество байт (если только не достигнут EOF). Но для интерактивных сырых потоков будет выполнено не более одного сырого чтения, и короткий результат не означает, что EOF неизбежен.294295[`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError) возникает, если нижележащий небуферизованный поток находится в неблокирующем режиме и в данный момент не имеет доступных данных.296297#### `read1(size=-1)`298299Читает и возвращает до *size* байт, выполняя не более одного вызова метода [`read()`](https://python-all.ru/3.4/library/io.html#io.RawIOBase.read) нижележащего небуферизованного потока. Это может быть полезно при реализации собственной буферизации поверх объекта [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase).300301#### `readinto(b)`302303Читает до `len(b)` байт в bytearray *b* и возвращает количество прочитанных байт.304305Как и [`read()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.read), может выполняться несколько чтений из нижележащего небуферизованного потока, если только последний не является интерактивным.306307[`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError) возникает, если нижележащий небуферизованный поток находится в неблокирующем режиме и в данный момент не имеет доступных данных.308309#### `write(b)`310311Записывает заданный объект [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) или [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray), *b*, и возвращает количество записанных байт (никогда не меньше `len(b)`, так как в случае неудачи записи будет вызвано исключение [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError)). В зависимости от конкретной реализации эти байты могут быть немедленно записаны в нижележащий поток или сохранены в буфере по соображениям производительности и задержки.312313В неблокирующем режиме возникает [`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError), если данные необходимо записать в небуферизованный поток, но он не может принять все данные без блокировки.314315### 16.2.3.2. Сырой файловый ввод/вывод316317#### `class io.FileIO(name, mode='r', closefd=True, opener=None)`318319[`FileIO`](https://python-all.ru/3.4/library/io.html#io.FileIO) представляет файл на уровне ОС, содержащий байтовые данные. Он реализует интерфейс [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) (а следовательно, и интерфейс [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase)).320321Параметр *name* может быть одним из двух:322323- строка символов или объект [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes), представляющий путь к файлу, который будет открыт;324- целое число, представляющее номер существующего файлового дескриптора на уровне ОС, к которому будет предоставлять доступ результирующий объект [`⟦/2FileIO`](https://python-all.ru/3.4/library/io.html#io.FileIO).325326Параметр *mode* может быть `'r'`, `'w'`, `'x'` или `'a'` для чтения (по умолчанию), записи, эксклюзивного создания или добавления. Файл будет создан, если он не существует, при открытии для записи или добавления; при открытии для записи он будет обрезан. [`FileExistsError`](https://python-all.ru/3.4/library/exceptions.html#FileExistsError) будет возбуждено, если файл уже существует при открытии для создания. Открытие файла для создания подразумевает запись, поэтому этот режим ведёт себя аналогично `'w'`. Добавьте `'+'` в режим, чтобы разрешить одновременное чтение и запись.327328Методы `read()` (при вызове с положительным аргументом), `readinto()` и `write()` этого класса будут выполнять только один системный вызов.329330Можно использовать собственный открыватель, передав вызываемый объект как *opener*. Внутренний файловый дескриптор для файлового объекта затем получается вызовом *opener* с аргументами (*name*, *flags*). *opener* должен возвращать открытый файловый дескриптор (если передать [`os.open`](https://python-all.ru/3.4/library/os.html#os.open) как *opener*, то поведение будет аналогично передаче `None`).331332Созданный файл является [*ненаследуемым*](https://python-all.ru/3.4/library/os.html#fd-inheritance).333334Примеры использования параметра *opener* см. во встроенной функции [`open()`](https://python-all.ru/3.4/library/functions.html#open).335336Изменено в версии 3.3: Добавлен параметр *opener*. Добавлен режим `'x'`.337338Изменено в версии 3.4: Файл теперь не наследуется.339340In addition to the attributes and methods from [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase) and [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase), [`FileIO`](https://python-all.ru/3.4/library/io.html#io.FileIO) provides the following data attributes:341342#### `mode`343344Режим, указанный в конструкторе.345346#### `name`347348Имя файла. Это дескриптор файла, если имя не указано в конструкторе.349350### 16.2.3.3. Буферизированные потоки351352Буферизированные потоки ввода-вывода предоставляют интерфейс более высокого уровня к устройству ввода-вывода, чем небуферизированный.353354#### `class io.BytesIO([initial_bytes])`355356Реализация потока, использующая буфер байтов в памяти. Наследует [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase). Буфер отбрасывается при вызове метода [`close()`](https://python-all.ru/3.4/library/io.html#io.IOBase.close).357358Аргумент *initial\_bytes* содержит необязательные начальные данные [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes).359360[`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO) предоставляет или переопределяет следующие методы в дополнение к методам из [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) и [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase):361362#### `getbuffer()`363364Возвращает доступное для чтения и записи представление содержимого буфера без его копирования. Изменение этого представления также прозрачно обновляет содержимое буфера:365366```python367>>> b = io.BytesIO(b"abcdef")368>>> view = b.getbuffer()369>>> view[2:4] = b"56"370>>> b.getvalue()371b'ab56ef'372```373374> **Примечание**375>376> Пока существует представление, объект [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO) не может быть изменён в размере или закрыт.377378Новое в версии 3.2.379380#### `getvalue()`381382Возвращает [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes), содержащий всё содержимое буфера.383384#### `read1()`385386В [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO) это эквивалентно `read()`.387388#### `class io.BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)`389390Буфер, обеспечивающий доступ более высокого уровня к читаемому последовательному объекту [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase). Наследует [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase). При чтении данных из этого объекта из нижележащего необработанного потока может запрашиваться больший объём данных, которые сохраняются во внутреннем буфере. Затем буферизованные данные могут быть прямо возвращены при последующих чтениях.391392Конструктор создаёт [`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader) для переданного читаемого потока *raw* и *buffer\_size*. Если *buffer\_size* опущен, используется [`DEFAULT_BUFFER_SIZE`](https://python-all.ru/3.4/library/io.html#io.DEFAULT_BUFFER_SIZE).393394[`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader) предоставляет или переопределяет следующие методы в дополнение к методам из [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) и [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase):395396#### `peek([size])`397398Возвращает байты из потока без продвижения позиции. Для выполнения вызова производится не более одного чтения из сырого потока. Количество возвращённых байт может быть меньше или больше запрошенного.399400#### `read([size])`401402Читает и возвращает *size* байт, или, если *size* не задан или отрицателен, до достижения EOF или пока вызов чтения не заблокируется в неблокирующем режиме.403404#### `read1(size)`405406Читает и возвращает до *size* байт, выполняя только один вызов к сырому потоку. Если хотя бы один байт уже находится в буфере, возвращаются только буферизованные байты. В противном случае выполняется один вызов чтения сырого потока.407408#### `class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)`409410Буфер, обеспечивающий доступ более высокого уровня к записываемому последовательному объекту [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase). Наследует [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase). При записи в этот объект данные обычно помещаются во внутренний буфер. Буфер будет сброшен в нижележащий объект [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) при следующих условиях:411412- когда буфер становится слишком мал для всех ожидающих данных;413- при вызове [`flush()`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter.flush);414- при запросе `seek()` (для объектов [`BufferedRandom`](https://python-all.ru/3.4/library/io.html#io.BufferedRandom));415- когда объект [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter) закрывается или уничтожается.416417Конструктор создаёт [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter) для переданного записываемого потока *raw*. Если *buffer\_size* не указан, по умолчанию используется [`DEFAULT_BUFFER_SIZE`](https://python-all.ru/3.4/library/io.html#io.DEFAULT_BUFFER_SIZE).418419[`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter) предоставляет или переопределяет следующие методы в дополнение к методам из [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase) и [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase):420421#### `flush()`422423Принудительно сбрасывает байты, находящиеся в буфере, в необработанный поток. Если необработанный поток блокируется, должно быть возбуждено исключение [`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError).424425#### `write(b)`426427Записывает объект [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes) или [`bytearray`](https://python-all.ru/3.4/library/functions.html#bytearray), *b* и возвращает количество записанных байт. В неблокирующем режиме возникает [`BlockingIOError`](https://python-all.ru/3.4/library/exceptions.html#BlockingIOError), если буфер необходимо выгрузить, но необработанный поток блокируется.428429#### `class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)`430431Буферизованный интерфейс для потоков с произвольным доступом. Он наследует [`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader) и [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter), а также поддерживает функциональность `seek()` и `tell()`.432433Конструктор создаёт читатель и писатель для позиционируемого необработанного потока, заданного в первом аргументе. Если *buffer\_size* опущен, по умолчанию используется [`DEFAULT_BUFFER_SIZE`](https://python-all.ru/3.4/library/io.html#io.DEFAULT_BUFFER_SIZE).434435[`BufferedRandom`](https://python-all.ru/3.4/library/io.html#io.BufferedRandom) способен на всё, что могут [`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader) или [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter).436437#### `class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE)`438439Буферизованный объект ввода-вывода, объединяющий два однонаправленных объекта [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase) – один читаемый, другой записываемый – в единую двунаправленную конечную точку. Он наследует [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase).440441*reader* и *writer* – это объекты [`RawIOBase`](https://python-all.ru/3.4/library/io.html#io.RawIOBase), предназначенные соответственно для чтения и записи. Если *buffer\_size* опущен, по умолчанию используется [`DEFAULT_BUFFER_SIZE`](https://python-all.ru/3.4/library/io.html#io.DEFAULT_BUFFER_SIZE).442443[`BufferedRWPair`](https://python-all.ru/3.4/library/io.html#io.BufferedRWPair) реализует все методы [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase), за исключением [`detach()`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase.detach), который возбуждает [`UnsupportedOperation`](https://python-all.ru/3.4/library/io.html#io.UnsupportedOperation).444445> **Предупреждение**446>447> [`BufferedRWPair`](https://python-all.ru/3.4/library/io.html#io.BufferedRWPair) не пытается синхронизировать доступ к своим базовым необработанным потокам. Не следует передавать ему один и тот же объект в качестве читателя и писателя; вместо этого используйте [`BufferedRandom`](https://python-all.ru/3.4/library/io.html#io.BufferedRandom).448449### 16.2.3.4. Текстовый ввод-вывод450451#### `class io.TextIOBase`452453Базовый класс для текстовых потоков. Этот класс предоставляет посимвольный и построчный интерфейс для потокового ввода-вывода. Метод `readinto()` отсутствует, поскольку строки Python неизменяемы. Он наследует [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase). Открытый конструктор отсутствует.454455[`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase) предоставляет или переопределяет следующие атрибуты данных и методы в дополнение к унаследованным от [`IOBase`](https://python-all.ru/3.4/library/io.html#io.IOBase):456457#### `encoding`458459Имя кодировки, используемой для декодирования байтов потока в строки и для кодирования строк в байты.460461#### `errors`462463Настройка обработки ошибок декодера или кодера.464465#### `newlines`466467Строка, кортеж строк или `None`, указывающие на переведённые на данный момент символы новой строки. В зависимости от реализации и начальных флагов конструктора это может быть недоступно.468469#### `buffer`470471Базовый бинарный буфер (экземпляр [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase)), с которым работает [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase). Это не часть API [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase) и может отсутствовать в некоторых реализациях.472473#### `detach()`474475Отделяет базовый бинарный буфер от [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase) и возвращает его.476477После отсоединения базового буфера [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase) переходит в неработоспособное состояние.478479Некоторые реализации [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase), например [`StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO), могут не иметь понятия базового буфера, и вызов этого метода приведёт к возбуждению [`UnsupportedOperation`](https://python-all.ru/3.4/library/io.html#io.UnsupportedOperation).480481Новое в версии 3.1.482483#### `read(size)`484485Читает не более *size* символов из потока и возвращает их в виде одной строки [`str`](https://python-all.ru/3.4/library/stdtypes.html#str). Если *size* отрицателен или равен `None`, читает до конца файла.486487#### `readline(size=-1)`488489Читает до символа новой строки или конца файла и возвращает одну строку `str`. Если поток уже достиг конца файла, возвращается пустая строка.490491Если указан *size*, будет прочитано не более *size* символов.492493#### `seek(offset[, whence])`494495Изменяет позицию в потоке на указанное значение *offset*. Поведение зависит от параметра *whence*. Значение по умолчанию для *whence* – `SEEK_SET`.496497- `SEEK_SET` или `0`: поиск от начала потока (по умолчанию); *offset* должен быть либо числом, возвращённым [`TextIOBase.tell()`](https://python-all.ru/3.4/library/io.html#io.TextIOBase.tell), либо нулём. Любое другое значение *offset* приводит к неопределённому поведению.498- `SEEK_CUR` или `1`: «поиск» на текущую позицию; *offset* должен быть нулём, что означает отсутствие операции (все остальные значения не поддерживаются).499- `SEEK_END` или `2`: переход в конец потока; *offset* должен быть равен нулю (другие значения не поддерживаются).500501Возвращает новую абсолютную позицию в виде непрозрачного числа.502503Новое в версии 3.1: Константы `SEEK_*`.504505#### `tell()`506507Возвращает текущую позицию в потоке в виде непрозрачного числа. Обычно это число не соответствует количеству байт в базовом двоичном хранилище.508509#### `write(s)`510511Записывает строку *s* в поток и возвращает количество записанных символов.512513#### `class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False)`514515Буферизированный текстовый поток поверх бинарного потока [`BufferedIOBase`](https://python-all.ru/3.4/library/io.html#io.BufferedIOBase). Наследует [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase).516517*encoding* задаёт имя кодировки, которая будет использоваться для декодирования или кодирования потока. По умолчанию используется [`locale.getpreferredencoding(False)`](https://python-all.ru/3.4/library/locale.html#locale.getpreferredencoding).518519*errors* – необязательная строка, определяющая, как обрабатывать ошибки кодирования и декодирования. Передача `'strict'` вызывает исключение [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError) при ошибке кодирования (значение по умолчанию `None` имеет тот же эффект), а `'ignore'` игнорирует ошибки. (Обратите внимание, что игнорирование ошибок кодирования может привести к потере данных.) `'replace'` вставляет замещающий символ (например, `'?'`) в места неверных данных. При записи можно использовать `'xmlcharrefreplace'` (замена соответствующей XML-ссылкой на символ) или `'backslashreplace'` (замена escape-последовательностями с обратной косой чертой). Допустимо любое другое имя обработки ошибок, зарегистрированное в [`codecs.register_error()`](https://python-all.ru/3.4/library/codecs.html#codecs.register_error).520521*newline* управляет обработкой концов строк. Может принимать значения `None`, `''`, `'\n'`, `'\r'` и `'\r\n'`. Работает следующим образом:522523- При чтении данных из потока, если *newline* равно `None`, включается режим [*универсальных концов строк*](https://python-all.ru/3.4/glossary.html#term-universal-newlines). Строки во входных данных могут заканчиваться на `'\n'`, `'\r'` или `'\r\n'`, и они преобразуются в `'\n'` перед возвратом вызывающему коду. Если значение равно `''`, режим универсальных концов строк также включён, но символы концов строк возвращаются вызывающему коду без преобразования. Если значение равно любому другому допустимому значению, входные строки завершаются только указанной строкой, и символ конца строки возвращается вызывающему коду без преобразования.524- При записи в поток, если *newline* равен `None`, все записанные символы `'\n'` преобразуются в системный разделитель строк по умолчанию [`os.linesep`](https://python-all.ru/3.4/library/os.html#os.linesep). Если *newline* равен `''` или `'\n'`, никакого преобразования не происходит. Если *newline* – любое другое допустимое значение, все записанные символы `'\n'` преобразуются в указанную строку.525526Если *line\_buffering* равно `True`, `flush()` подразумевается при вызове write, содержащем символ новой строки.527528Если *write\_through* равно `True`, вызовы `write()` гарантированно не буферизируются: любые данные, записанные в объект [`TextIOWrapper`](https://python-all.ru/3.4/library/io.html#io.TextIOWrapper), немедленно передаются его нижележащему бинарному *buffer*.529530Изменено в версии 3.3: Добавлен аргумент *write\_through*.531532Изменено в версии 3.3: Кодировка по умолчанию *encoding* теперь `locale.getpreferredencoding(False)` вместо `locale.getpreferredencoding()`. Не меняйте временно кодировку локали с помощью [`locale.setlocale()`](https://python-all.ru/3.4/library/locale.html#locale.setlocale), используйте текущую кодировку локали вместо предпочитаемой пользователем.533534[`TextIOWrapper`](https://python-all.ru/3.4/library/io.html#io.TextIOWrapper) предоставляет один атрибут в дополнение к атрибутам [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase) и его родительских классов:535536#### `line_buffering`537538Определяет, включена ли построчная буферизация.539540#### `class io.StringIO(initial_value='', newline='\n')`541542Поток в памяти для текстового ввода-вывода. Текстовый буфер очищается при вызове метода [`close()`](https://python-all.ru/3.4/library/io.html#io.IOBase.close).543544Начальное значение буфера можно задать, указав *initial\_value*. Если преобразование концов строк включено, символы новой строки будут кодироваться так, как если бы они были записаны через [`write()`](https://python-all.ru/3.4/library/io.html#io.TextIOBase.write). Поток позиционируется в начало буфера.545546Аргумент *newline* работает так же, как в [`TextIOWrapper`](https://python-all.ru/3.4/library/io.html#io.TextIOWrapper). По умолчанию только символ `\n` считается концом строки, и никакого преобразования концов строк не выполняется. Если *newline* установлен в `None`, символы новой строки записываются как `\n` на всех платформах, но при чтении всё равно выполняется универсальное декодирование концов строк.547548[`StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO) предоставляет этот метод в дополнение к методам из [`TextIOBase`](https://python-all.ru/3.4/library/io.html#io.TextIOBase) и его родительских классов:549550#### `getvalue()`551552Возвращает `str`, содержащий всё содержимое буфера. Символы новой строки декодируются так, как если бы они были прочитаны через [`read()`](https://python-all.ru/3.4/library/io.html#io.TextIOBase.read), хотя позиция в потоке не изменяется.553554Пример использования:555556```python557import io558559output = io.StringIO()560output.write('First line.\n')561print('Second line.', file=output)562563# Извлечь содержимое файла – это будет564# 'Первая строка.565Вторая строка.566'567contents = output.getvalue()568569# Закрыть объект и освободить буфер памяти –570# .getvalue() теперь будет вызывать исключение.571output.close()572```573574#### `class io.IncrementalNewlineDecoder`575576Вспомогательный кодек для декодирования концов строк в режиме [*универсальных концов строк*](https://python-all.ru/3.4/glossary.html#term-universal-newlines). Наследует [`codecs.IncrementalDecoder`](https://python-all.ru/3.4/library/codecs.html#codecs.IncrementalDecoder).577578## 16.2.4. Производительность579580В этом разделе рассматривается производительность предоставленных конкретных реализаций ввода-вывода.581582### 16.2.4.1. Двоичный ввод-вывод583584Читая и записывая только большие блоки данных, даже когда пользователь запрашивает один байт, буферизованный ввод-вывод скрывает любую неэффективность вызова и выполнения небуферизованных процедур ввода-вывода операционной системы. Выигрыш зависит от ОС и типа выполняемого ввода-вывода. Например, в некоторых современных ОС, таких как Linux, небуферизованный дисковый ввод-вывод может быть таким же быстрым, как буферизованный. Однако суть в том, что буферизованный ввод-вывод обеспечивает предсказуемую производительность независимо от платформы и нижележащего устройства. Поэтому для двоичных данных почти всегда предпочтительнее использовать буферизованный ввод-вывод, а не небуферизованный.585586### 16.2.4.2. Текстовый ввод-вывод587588Текстовый ввод-вывод через бинарное хранилище (например, файл) значительно медленнее, чем бинарный ввод-вывод через то же хранилище, потому что требуется преобразование между юникодом и бинарными данными с помощью символьного кодека. Это может стать заметным при обработке огромных объёмов текстовых данных, таких как большие файлы журналов. Кроме того, `TextIOWrapper.tell()` и `TextIOWrapper.seek()` работают довольно медленно из-за используемого алгоритма восстановления.589590[`StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO), однако, является собственным контейнером юникода в памяти и будет демонстрировать скорость, аналогичную [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO).591592### 16.2.4.3. Многопоточность593594Объекты [`FileIO`](https://python-all.ru/3.4/library/io.html#io.FileIO) являются потокобезопасными в той степени, в какой потокобезопасны системные вызовы (например, `read(2)` в Unix), которые они обёртывают.595596Буферизированные бинарные объекты (экземпляры [`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader), [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter), [`BufferedRandom`](https://python-all.ru/3.4/library/io.html#io.BufferedRandom) и [`BufferedRWPair`](https://python-all.ru/3.4/library/io.html#io.BufferedRWPair)) защищают свои внутренние структуры с помощью блокировки; поэтому их можно безопасно вызывать из нескольких потоков одновременно.597598Объекты [`TextIOWrapper`](https://python-all.ru/3.4/library/io.html#io.TextIOWrapper) не являются потокобезопасными.599600### 16.2.4.4. Реентерабельность601602Буферизированные бинарные объекты (экземпляры [`BufferedReader`](https://python-all.ru/3.4/library/io.html#io.BufferedReader), [`BufferedWriter`](https://python-all.ru/3.4/library/io.html#io.BufferedWriter), [`BufferedRandom`](https://python-all.ru/3.4/library/io.html#io.BufferedRandom) и [`BufferedRWPair`](https://python-all.ru/3.4/library/io.html#io.BufferedRWPair)) не являются реентерабельными. Хотя реентерабельные вызовы обычно не происходят в нормальных ситуациях, они могут возникнуть при выполнении ввода-вывода в обработчике [`сигнала`](https://python-all.ru/3.4/library/signal.html#module-signal). Если поток попытается повторно войти в буферизированный объект, к которому он уже обращается, вызывается [`RuntimeError`](https://python-all.ru/3.4/library/exceptions.html#RuntimeError). Обратите внимание, это не запрещает другому потоку входить в буферизированный объект.603604Сказанное выше неявно распространяется и на текстовые файлы, поскольку функция [`open()`](https://python-all.ru/3.4/library/functions.html#open) обёртывает буферизированный объект внутри [`TextIOWrapper`](https://python-all.ru/3.4/library/io.html#io.TextIOWrapper). Это включает стандартные потоки и, следовательно, также влияет на встроенную функцию [`print()`](https://python-all.ru/3.4/library/functions.html#print).605