Модуль IO в Python на примерах BytesIO и StringIO
Модуль Python io позволяет нам управлять операциями ввода и вывода, связанными с файлами. Преимущество использования модуля ввода-вывода заключается в том, что доступные классы и функции позволяют нам расширять функциональность, чтобы разрешить запись в данные Unicode.
Модуль ввода-вывода Python
Есть много способов использования модуля io для выполнения потоковых и буферных операций в Python. Мы продемонстрируем здесь множество примеров, чтобы доказать это.
BytesIO
Как и в случае с переменными, данные могут храниться в байтах в буфере в памяти, когда мы используем операции байтового ввода-вывода модуля io.
Вот пример программы, чтобы продемонстрировать это:

StringIO
Мы даже можем использовать StringIO, который очень похож по использованию на BytesIO. Вот пример программы:

Кроме того, мы использовали метод print с необязательным аргументом, чтобы указать поток ввода-вывода переменной, который полностью совместим с оператором печати.
Чтение с использованием StringIO
Записав некоторые данные в буфер StringIO, мы также можем их прочитать. Посмотрим на фрагмент кода:

Чтение файла с помощью StringIO
Также можно прочитать файл и передать его по сети в байтах. Модуль io можно использовать для преобразования мультимедийного файла, например изображения, в байты. Вот пример программы:
Модуль IO в Python
Модуль IO очень полезен, когда вы хотите выполнять операции ввода-вывода, связанные с файлами (например, чтение / запись файлов).
Хотя вы можете использовать обычные методы read() и write() для чтения или записи в файл, но этот модуль дает нам гораздо больше гибкости в отношении этих операций.

Этот модуль является частью стандартной библиотеки, поэтому нет необходимости устанавливать его отдельно с помощью pip.
Чтобы импортировать модуль io, мы можем сделать следующее:
В модуле io есть 2 общих класса, которые нам очень пригодятся:
- BytesIO -> операции ввода-вывода с байтовыми данными;
- StringIO -> операции ввода-вывода для строковых данных.
Мы можем получить доступ к этим классам с помощью io.BytesIO и io.StringIO .
Класс Python BytesIO
Здесь мы можем хранить наши данные в виде байтов ( b» ). Когда мы используем io.BytesIO , данные хранятся в буфере в памяти.
Мы можем получить экземпляр байтового потока с помощью конструктора:
Обратите внимание, что мы передаем байтовую строку (с префиксом b ).
Прямо сейчас bytes_stream — это просто дескриптор байтового потока.
Чтобы напечатать данные внутри буфера, нам нужно использовать bytes_stream.getvalue() .
Здесь getvalue() берет значение байтовой строки из дескриптора.
Поскольку байтовая строка \x0A является представлением ASCII новой строки (‘\ n’), мы получаем следующий вывод:
Теперь всегда рекомендуется закрывать дескриптор буфера после того, как мы закончили свою работу. Это также необходимо для того, чтобы освободить всю память, выделенную для буфера.
Чтобы закрыть буфер, используйте:
Класс Python StringIO
Класс io.StringIO может читать данные, относящиеся к строке, из буфера StringIO.
Мы можем читать из строкового буфера с помощью string_stream.read() и писать с помощью string_stream.write() .
Мы можем распечатать содержимое с помощью getvalue() .
Поскольку мы пишем в тот же буфер, новое содержимое, очевидно, перезапишет старое.
Чтение из буфера StringIO
Подобно записи, мы также можем читать из буфера buffer.read() используя buffer.read() .
Как видите, содержимое теперь находится внутри буфера чтения, который печатается с помощью buffer.read() .
Чтение файла с помощью io
Мы также можем использовать метод io.open() для прямого чтения из файла, аналогично чтению из файлового объекта.
Здесь этот модуль дает нам возможность выбора между буферизованным и небуферизованным чтением.
Например, следующее будет использовать буферизованное чтение для чтения файла, установив buffering = SIZE . Если SIZE = 0, буферизации не будет.
Предположим, sample.txt имеет следующее содержимое:
Как видите, файл прочитан успешно. Здесь io прочитает файл, используя буфер размером примерно 5 байт.
io — Основные инструменты для работы с потоками¶
Модуль io предоставляет основные возможности Python для работы с различными типами ввода-вывода. Существует три основных типа ввода-вывода: текстовый I/O, бинарный I/O и необработанный I/O. Это общие категории, и для каждой из них можно использовать различные поддерживаемые (backing) хранилища. Объект, принадлежащий к любой из категорий, называется файловым объектом . Другие общие термины — поток и файловый объект.
Независимо от своей категории, у каждого объекта потока также будут различные возможности: он может быть доступен только для чтения, только для записи или чтения-записи. Он также может разрешать произвольный доступ (поиск вперед или назад в любое место) или только последовательный доступ (например, в случае сокета или канала (pipe)).
Все потоки внимательно относятся к типу данных, которые вы им предоставляете. Например, передача объекта str методу write() двоичного потока вызовет TypeError . Так же как и предоставление объекта bytes методу write() текстового потока.
Изменено в версии 3.3: Операции, которые раньше вызывали IOError , теперь вызывают OSError , поскольку IOError теперь является псевдонимом OSError .
Текстовый ввод/вывод¶
Текстовый ввод-вывод ожидает и производит объекты str . Это означает, что всякий раз, когда поддерживаемое хранилище изначально состоит из байтов (например, в случае файла), кодирование и декодирование данных выполняется прозрачно, а также необязательный перевод специфичных для платформы символов новой строки.
Самый простой способ создать текстовый поток — использовать open() , при желании указав кодировку:
Текстовые потоки в памяти также доступны как объекты StringIO :
API текстового потока подробно описан в документации TextIOBase .
Двоичный ввод/вывод¶
Двоичный ввод-вывод (также называемый буферизованный I/O) ожидает байтовые объекты и производит bytes объекты. Кодирование, декодирование или перевод новой строки не выполняется. Данная категория потоков может использоваться для всех видов нетекстовых данных, а также когда требуется ручное управление обработкой текстовых данных.
Самый простой способ создать двоичный поток — использовать open() с ‘b’ в строке режима:
Двоичные потоки в памяти также доступны как объекты BytesIO :
API двоичного потока подробно описан в документации BufferedIOBase .
Другие модули библиотеки могут предоставлять дополнительные способы создания текстовых или двоичных потоков. См., например, socket.socket.makefile() .
Необработанный ввод-вывод¶
Необработанный ввод-вывод (также называемый небуферизованный I/O) обычно используется в качестве низкоуровневого строительного блока для двоичных и текстовых потоков; редко бывает полезно напрямую управлять необработанным потоком из пользовательского кода. Тем не менее, вы можете создать необработанный поток, открыв файл в двоичном режиме с отключенной буферизацией:
API необработанного потока подробно описан в документации RawIOBase .
Интерфейс модуля высокого уровня¶
Тип int, содержащий размер буфера по умолчанию, используемый классами буферизованного ввода-вывода модуля. open() использует размер файла blksize (полученный os.stat() ), если это возможно.
Псевдоним встроенной функции open() .
Функция вызывает событие аудита open с аргументами path , mode и flags . Аргументы mode и flags могли быть изменены или выведены из исходного вызова.
io. open_code ( path ) ¶
Открывает предоставленный файл в режиме ‘rb’ . Функцию следует использовать, когда намерение состоит в том, чтобы рассматривать содержимое как исполняемый код.
path должен быть str и абсолютным путём.
Поведение функции может отменяться более ранним вызовом PyFile_SetOpenCodeHook() . Однако если предположить, что path — str и абсолютный путь, open_code(path) всегда должен вести себя так же, как open(path, ‘rb’) . Переопределение поведения предназначено для дополнительной проверки или предварительной обработки файла.
Добавлено в версии 3.8.
Псевдоним совместимости для встроенного исключения BlockingIOError .
exception io. UnsupportedOperation ¶
Исключение, наследующее OSError и ValueError , которое возникает при вызове неподдерживаемой операции в потоке.
Потоки в памяти¶
Также можно использовать str или байтовый объект в качестве файла как для чтения, так и для записи. Для строк StringIO может использоваться как файл, открытый в текстовом режиме. BytesIO можно использовать как файл, открытый в двоичном режиме. Оба предоставляют полные возможности чтения-записи с произвольным доступом.
sys Содержит стандартные потоки ввода-вывода: sys.stdin , sys.stdout и sys.stderr .
Иерархия классов¶
Реализация потоков ввода-вывода организована в виде иерархии классов. Сначала абстрактные базовые классы (ABC), которые используются для определения различных категорий потоков, затем классы, обеспечивающие стандартные реализации потоков.
Примечание
Абстрактные базовые классы также предоставляют реализации по умолчанию некоторых методов, чтобы помочь реализации потоковых классов. Например, BufferedIOBase предоставляет неоптимизированные реализации readinto() и readline() .
На вершине иерархии ввода-вывода находится абстрактный базовый класс IOBase . Он определяет базовый интерфейс для потока. Обратите внимание, однако, что нет разделения между чтением и записью в потоки; реализациям разрешено вызывать UnsupportedOperation , если они не поддерживают данную операцию.
RawIOBase ABC расширяет IOBase . Он занимается чтением и записью байтов в поток. FileIO подклассы RawIOBase для обеспечения интерфейса для файлов в файловой системе компьютера.
BufferedIOBase ABC занимается буферизацией необработанного байтового потока ( RawIOBase ). Его подклассы, BufferedWriter , BufferedReader и BufferedRWPair , буферные потоки, которые доступны для чтения, записи, а также для чтения и записи. BufferedRandom предоставляет буферизованный интерфейс для потоков произвольного доступа. Другой подкласс BufferedIOBase , BytesIO , представляет собой поток байтов в памяти.
TextIOBase ABC, другой подкласс IOBase , работающий с потоками, байты которых представляют текст, и обрабатывает кодирование и декодирование в строки и из строк. TextIOWrapper , который его расширяет, представляет собой буферизованный текстовый интерфейс для буферизованного необработанного потока ( BufferedIOBase ). Наконец, StringIO — поток текста в памяти.
Имена аргументов не являются частью спецификации, и только аргументы open() предназначены для использования в качестве ключевых аргументов.
В следующей таблице приведены ABC, предоставляемые модулем io :
| ABC | Наследуется | Методы заглушки | Методы и свойства миксины |
|---|---|---|---|
| IOBase | fileno , seek , и truncate | close , closed , __enter__ , __exit__ , flush , isatty , __iter__ , __next__ , readable , readline , readlines , seekable , tell , writable , и writelines | |
| RawIOBase | IOBase | readinto и write | Унаследованные IOBase методы, read , и readall |
| BufferedIOBase | IOBase | detach , read , read1 , и write | Унаследованные IOBase методы, readinto , и readinto1 |
| TextIOBase | IOBase | detach , read , readline , и write | Унаследованные IOBase методы, encoding , errors и newlines |
Базовые классы ввода-вывода¶
Абстрактный базовый класс для всех классов ввода-вывода, воздействующий на потоки байтов. Общедоступного конструктора нет.
Класс предоставляет пустые абстрактные реализации для многих методов, выборочно переопределяемые производными классами; реализации по умолчанию представляют собой файл, который нельзя прочитать, записать или найти.
Несмотря на то, что IOBase не объявляет read() или write() , потому что их сигнатуры будут различаться, реализации и клиенты должны рассматривать данные методы как часть интерфейса. Кроме того, реализации могут вызывать ValueError (или UnsupportedOperation ), когда вызываются операции, которые они не поддерживают.
Базовый тип, используемый для двоичных данных bytes , считываемых из файла или записываемых в файл. Остальные байтовые объекты также принимаются в качестве аргументов метода. Классы текстового ввода-вывода работают с str данными.
Обратите внимание, что вызов любого метода (даже запросов) в закрытом потоке не определён. В этом случае реализации могут вызвать ValueError .
IOBase (и его подклассы) поддерживает протокол итератора, что означает, что объект IOBase может быть повторен, отдавая строки в потоке. Строки определяются немного по-разному в зависимости от того, является ли поток двоичным потоком (дающим байты) или текстовым потоком (дающим символьные строки). См. readline() ниже.
IOBase также является менеджером контекста и поэтому поддерживает оператор with . В примере file закрывается после завершения набора операторов with ,— даже если возникает исключение:
IOBase предоставляет следующие атрибуты данных и методы:
Сбросить и закрыть поток. Метод не действует, если файл уже закрыт. После закрытия файла любая операция с файлом (например, чтение или запись) вызовет ValueError .
Для удобства можно вызывать данный метод более одного раза; однако только первый вызов будет приводить к эффекту.
True , если поток закрыт.
Возвращает базовый файловый дескриптор (целое число) потока, если он существует. Возникает OSError , если объект ввода-вывода не использует файловый дескриптор.
Если возможно, очистите буферы записи потока. Ничего не делает для потоков, предназначенных только для чтения и неблокирующих потоков.
Возвращает True , если поток интерактивный (т.е. подключён к терминалу/tty-устройству).
Возвращает True , если поток можно прочитать. Если False , read() вызывает OSError .
Читает и возвращает одну строку из потока. Если указан size, будет прочитано не более size байтов.
Для двоичных файлов терминатор строки всегда b’\n’ ; для текстовых файлов аргумент newline для open() может использоваться для выбора распознаваемых ограничителей строки.
Читает и возвращает список строк из потока. hint можно указать для управления количеством прочитанных строк: больше не будут считываться строки, если общий размер (в байтах/символах) всех строк на данный момент превышает hint.
Обратите внимание, что уже можно выполнять итерацию файловых объектов с помощью for line in file: . без вызова file.readlines() .
seek ( offset, whence=SEEK_SET ) ¶
Изменить позицию потока на данный байтовый offset. offset интерпретируется относительно позиции, обозначенной whence. Значение по умолчанию для whence — SEEK_SET . Значения для whence равны:
- SEEK_SET или 0 — начало потока (по умолчанию); offset должен быть нулевым или положительным.
- SEEK_CUR или 1 — текущая позиция в потоке; offset может быть отрицательным.
- SEEK_END или 2 — конец потока; offset обычно отрицательный.
Возвращает новую абсолютную позицию.
Добавлено в версии 3.1: Константы SEEK_* .
Добавлено в версии 3.3: Некоторые операционные системы могут поддерживать дополнительные значения, например os.SEEK_HOLE или os.SEEK_DATA . Допустимые значения для файла могут зависеть от того, открыт ли он в текстовом или двоичном режиме.
Возвращает True , если поток поддерживает произвольный доступ. Если False , seek() , tell() и truncate() вызовут OSError .
Возвращает текущую позицию потока.
Изменить размер потока до заданного size в байтах (или текущей позиции, если size не указан). Текущая позиция в потоке не изменяется. Изменение размера может увеличить или уменьшить текущий размер файла. В случае расширения содержимое новой файловой области зависит от платформы (в большинстве систем дополнительные байты заполняются нулями). Возвращается новый размер файла.
Изменено в версии 3.5: Windows теперь будет заполнять файлы нулями при расширении.
Возвращает True , если поток поддерживает запись. Если False , write() и truncate() вызовут OSError .
Записать список строк в поток. Разделители строк не добавляются, поэтому обычно у каждой из предоставленных строк есть разделитель строк в конце.
Подготовиться к разрушению объекта. IOBase предоставляет реализацию этого метода по умолчанию, которая вызывает метод экземпляра close() .
class io. RawIOBase ¶
Базовый класс для необработанного двоичного ввода-вывода. Он наследует IOBase . Общедоступного конструктора нет.
Необработанный двоичный ввод-вывод обычно предоставляет низкоуровневый доступ к базовому устройству ОС или API и не пытается инкапсулировать его в высокоуровневые примитивы (оставлено для буферизованного ввода-вывода и текстового ввода-вывода, описанного ниже на этой странице).
Помимо атрибутов и методов из IOBase , RawIOBase предоставляет следующие методы:
Читает до size байт из объекта и возвращает их. Для удобства, если size не указан или -1, возвращаются все байты до EOF. В противном случае выполняется только один системный вызов. Может возвращаться меньше size байт, если вызов операционной системы возвращает меньше size байт.
Если возвращается 0 байтов, а size не был 0, это указывает на конец файла. Если объект находится в неблокирующем режиме и нет доступных байтов, возвращается None .
Реализация по умолчанию относится к readall() и readinto() .
Читает и возвращает все байты из потока до EOF, используя при необходимости несколько вызовов потока.
Считывает байты в заранее выделенный, доступный для записи байтовым объектом b и возвращает количество прочитанных байтов. Например, b может быть bytearray . Если объект находится в неблокирующем режиме и нет доступных байтов, возвращается None .
Записать заданный байтовый объект , b в базовый необработанный поток и возвращает количество записанных байтов. Может быть меньше, чем длина b в байтах, в зависимости от специфики базового необработанного потока, особенно если он находится в неблокирующем режиме. None возвращается, если необработанный поток не настроен на блокировку и ни один байт не может быть легко записан в него. Вызывающий может освободить или изменить b после возврата из этого метода, поэтому реализация должна обращаться к b только во время вызова метода.
class io. BufferedIOBase ¶
Базовый класс для двоичных потоков, поддерживающих какую-то буферизацию. Он наследует IOBase . Общедоступного конструктора нет.
Основное отличие от RawIOBase заключается в том, что методы read() , readinto() и write() будут пытаться (соответственно) прочитать столько ввода, сколько запрошено, или использовать весь данный вывод за счет выполнения, возможно, более одного системного вызова.
Кроме того, данные методы могут вызывать BlockingIOError , если базовый необработанный поток находится в неблокирующем режиме и не может принимать или передавать достаточно данных; в отличие от своих аналогов RawIOBase , они никогда не вернут None .
Кроме того, у метода read() нет реализации по умолчанию, относящейся к readinto() .
Типичная реализация BufferedIOBase не должна наследовать от реализации RawIOBase , а должна оборачиваться, как это делают BufferedWriter и BufferedReader .
BufferedIOBase предоставляет или переопределяет данные методы и атрибуты в дополнение к тем из IOBase :
Базовый необработанный поток (экземпляр RawIOBase ), с которым работает BufferedIOBase . Не является частью API BufferedIOBase и может отсутствовать в некоторых реализациях.
Отделить базовый необработанный поток от буфера и возвращает его.
После отсоединения необработанного потока буфер находится в непригодном для использования состоянии.
У некоторых буферов, таких как BytesIO , нет концепции единого необработанного потока, возвращаемого данным методом. Вызывает UnsupportedOperation .
Добавлено в версии 3.1.
Чтение и возвращение до size байт. Если аргумент пропущен, None или отрицательный, данные считываются и возвращаются до достижения EOF. Пустой объект bytes возвращается, если поток уже находится в EOF.
Если аргумент положительный, а базовый необработанный поток не является интерактивным, может быть выполнено несколько необработанных чтений, чтобы удовлетворить счетчику байтов (если EOF не будет достигнут первым). Но для интерактивных необработанных потоков будет выполнено не более одного необработанного чтения, и короткий результат не означает, что EOF неизбежен.
BlockingIOError возникает, если базовый необработанный поток находится в неблокирующем режиме и в настоящий момент нет доступных данных.
Чтение и возвращение до size байт с помощью не более одного вызова метода read() (или readinto() ) базового необработанного потока. Может быть полезно, если вы реализуете собственную буферизацию поверх объекта BufferedIOBase .
Если size — -1 (по умолчанию), возвращается произвольное количество байтов (больше нуля, если не достигнут EOF).
Считывает байты в заранее выделенный, доступный для записи байтовый объект b и возвращает количество прочитанных байтов. Например, b может быть bytearray .
Как и read() , базовому необработанному потоку может быть выполнено несколько операций чтения, если последний не является интерактивным.
BlockingIOError возникает, если базовый необработанный поток находится в неблокирующем режиме и в данный момент нет доступных данных.
Читает байты в предварительно выделенный, доступный для записи байтового объекта b, используя не более одного вызова метода read() (или readinto() ) базового необработанного потока. Возвращает количество прочитанных байтов.
BlockingIOError возникает, если базовый необработанный поток находится в неблокирующем режиме и в настоящий момент нет доступных данных.
Добавлено в версии 3.5.
Пишет заданный байтовый объект b и возвращает количество записанных байтов (всегда равное длине b в байтах, поскольку в случае сбоя записи будет вызвано OSError ). В зависимости от фактической реализации эти байты могут быть легко записаны в базовый поток или сохранены в буфере по причинам производительности и задержки.
В неблокирующем режиме вызывается BlockingIOError , если данные необходимо записать в необработанный поток, но он не может принять все данные без блокировки.
Вызывающий может освободить или изменить b после возврата из этого метода, поэтому реализация должна обращаться к b только во время вызова метода.
Ввод-вывод необработанных файлов¶
FileIO представляет собой файл уровня ОС, содержащий данные в байтах. Он реализует интерфейс RawIOBase (и, следовательно, интерфейс IOBase ).
name может быть одним из двух:
- символьная строка или объект bytes , представляющий путь к файлу, который будет открыт. В этом случае значение closefd должно быть True (по умолчанию), иначе возникнет ошибка.
- целое число, представляющее номер существующего файлового дескриптора уровня ОС, к которому получившийся объект FileIO предоставит доступ. Когда объект FileIO закрыт, этот fd также будет закрыт, если closefd не установлен в False .
mode может быть ‘r’ , ‘w’ , ‘x’ или ‘a’ для чтения (по умолчанию), записи, исключительного создания или добавления. Файл будет создан, если он не существует при открытии для записи или добавления; он будет обрезан при открытии для записи. Будет вызвано FileExistsError , если он уже существует при открытии для создания. Открытие файла для создания подразумевает запись, поэтому этот режим ведет себя аналогично ‘w’ . Добавьте ‘+’ в режим, чтобы разрешить одновременное чтение и запись.
Методы read() (при вызове с положительным аргументом), readinto() и write() этого класса будут выполнять только один системный вызов.
Можно использовать настраиваемый открыватель, передав вызываемый объект как opener. Базовый файловый дескриптор для файлового объекта получается путём вызова opener с (name, flags). opener должен возвращать дескриптор открытого файла (передача os.open как opener приводит к функциональности, аналогичной передаче None ).
Вновь созданный файл — ненаследуемый .
См. встроенную функцию open() для примеров использования параметра opener.
Изменено в версии 3.3: Добавлен параметр opener. Добавлен режим ‘x’ .
Изменено в версии 3.4: Теперь файл не наследуется.
Помимо атрибутов и методов из IOBase и RawIOBase , FileIO предоставляет следующие атрибуты данных:
Режим, указанный в конструкторе.
Имя файла. Файловый дескриптор файла, если в конструкторе не указано имя.
Буферизованные потоки¶
Буферизованные потоки ввода-вывода предоставляют интерфейс более высокого уровня для устройства ввода-вывода, чем необработанный ввод-вывод.
class io. BytesIO ( [ initial_bytes ] ) ¶
Реализация потока с использованием байтового буфера в памяти. Он наследует BufferedIOBase . Буфер сбрасывается при вызове метода close() .
Необязательный аргумент initial_bytes — байтовый объект , который содержит исходные данные.
BytesIO предоставляет или отменяет данные методы в дополнение к методам из BufferedIOBase и IOBase :
Возвращает доступное для чтения и записи представление содержимого буфера без его копирования. Кроме того, изменение представления прозрачно обновит содержимое буфера:
Пока существует представление, нельзя изменить размер или закрыть объект BytesIO .
Добавлено в версии 3.2.
Возвращает bytes , содержащий все содержимое буфера.
В BytesIO это то же самое, что и read() .
Изменено в версии 3.7: Аргумент size теперь необязателен.
В BytesIO это то же самое, что и readinto() .
Добавлено в версии 3.5.
Буфер, обеспечивающий доступ более высокого уровня к читаемому последовательному объекту RawIOBase . Он наследует BufferedIOBase . При чтении данных из этого объекта может запрашиваться больший объем данных из базового необработанного потока и сохранён во внутреннем буфере. Буферизованные данные могут возвращаться непосредственно при последующих чтениях.
Конструктор создаёт BufferedReader для данного читаемого потока raw и buffer_size. Если buffer_size пропущен, используется DEFAULT_BUFFER_SIZE .
BufferedReader предоставляет или отменяет эти методы в дополнение к методам из BufferedIOBase и IOBase :
Возвращение байтов из потока без продвижения позиции. Для удовлетворения запроса выполняется не более одного однократного чтения необработанного потока. Количество возвращенных байтов может быть меньше или больше запрошенного.
Читает и возвращает size байтов, или, если size не задано или отрицательно, до EOF или если вызов чтения блокируется в неблокирующем режиме.
Чтение и возвращение до size байтов только с одним вызовом необработанного потока. Если в буфере находится хотя бы один байт, возвращаются только буферизованные байты. В противном случае выполняется один вызов чтения необработанного потока.
Изменено в версии 3.7: Аргумент size теперь необязателен.
Буфер, обеспечивающий высокоуровневый доступ к записываемому последовательному объекту RawIOBase . Он наследует BufferedIOBase . При записи в этот объект данные обычно помещаются во внутренний буфер. Буфер будет записан в базовый объект RawIOBase при различных условиях, в том числе:
- когда буфер становится слишком маленьким для всех ожидающих данных;
- когда вызывается flush() ;
- при запросе seek() (для объектов BufferedRandom );
- когда объект BufferedWriter закрыт или уничтожен.
Конструктор создаёт BufferedWriter для данного записываемого потока raw. Если buffer_size не указан, по умолчанию используется DEFAULT_BUFFER_SIZE .
BufferedWriter предоставляет или отменяет данные методы в дополнение к методам из BufferedIOBase и IOBase :
Перевести байты, хранящиеся в буфере, в необработанный поток. Если необработанный поток блокируется, следует вызвать BlockingIOError .
Записать байтовый объект , b и возвращает количество записанных байтов. В неблокирующем режиме возникает BlockingIOError , если необходимо записать буфер, но необработанный поток блокируется.
class io. BufferedRandom ( raw, buffer_size=DEFAULT_BUFFER_SIZE ) ¶
Буферизованный интерфейс для потоков произвольного доступа. Он наследует BufferedReader и BufferedWriter .
Конструктор создаёт средства чтения и записи для исходного потока с возможностью поиска, указанного в первом аргументе. Если buffer_size пропущен, по умолчанию используется DEFAULT_BUFFER_SIZE .
BufferedRandom способен на всё, что может сделать BufferedReader или BufferedWriter . Кроме того, гарантированно будут реализованы seek() и tell() .
class io. BufferedRWPair ( reader, writer, buffer_size=DEFAULT_BUFFER_SIZE ) ¶
Буферизованный объект ввода-вывода, объединяющий два однонаправленных объекта RawIOBase — один для чтения, другой для записи — в одну двунаправленную конечную точку. Он наследует BufferedIOBase .
reader и writer — объекты RawIOBase , которые доступны для чтения и записи соответственно. Если buffer_size пропущен, по умолчанию используется DEFAULT_BUFFER_SIZE .
BufferedRWPair реализует все методы BufferedIOBase , за исключением detach() , который вызывает UnsupportedOperation .
BufferedRWPair не пытается синхронизировать доступ к своим базовым необработанным потокам. Вы не должны передавать ему тот же объект, что и читатель и писатель; использовать вместо него BufferedRandom .
Текстовый ввод/вывод¶
Базовый класс для текстовых потоков. Класс предоставляет символьный и линейный интерфейс для потокового ввода-вывода. Он наследует IOBase . Общедоступного конструктора нет.
TextIOBase предоставляет или отменяет эти атрибуты данных и методы в дополнение к атрибутам из IOBase :
Имя кодировки, используемой для декодирования байтов потока в строки и для кодирования строк в байты.
Ошибка настройки декодера или кодировщика.
Строка, кортеж строк или None , указывающий на переведенные на данный момент новые строки. В зависимости от реализации и начальных флагов конструктора может быть недоступно.
Базовый двоичный буфер (экземпляр BufferedIOBase ), с которым работает TextIOBase . Не является частью API TextIOBase и может отсутствовать в некоторых реализациях.
Отделить нижележащий двоичный буфер от TextIOBase и возвращает его.
После отсоединения нижележащего буфера TextIOBase находится в непригодном для использования состоянии.
Некоторые реализации TextIOBase (например, StringIO ) могут не содержать концепции базового буфера, и вызов этого метода вызовет UnsupportedOperation .
Добавлено в версии 3.1.
Читает и возвращает не более size символов из потока как один str . Если size отрицательное значение или None , считывается до EOF.
Читает до новой строки или EOF и возвращает один str . Если поток уже находится в EOF, возвращается пустая строка.
Если указан size, будет прочитано не более size символов.
seek ( offset, whence=SEEK_SET ) ¶
Изменить позицию потока на данную offset. Поведение зависит от параметра whence. Значение по умолчанию для whence — SEEK_SET .
- SEEK_SET или 0 : поиск с начала потока (по умолчанию); offset должен быть либо числом, возвращаемым TextIOBase.tell() , либо нулем. Любое другое значение offset приводит к неопределенному поведению.
- SEEK_CUR или 1 : «поиск» к текущей позиции; offset должен быть равен нулю, что не является операцией (все другие значения не поддерживаются).
- SEEK_END или 2 : перейти к концу потока; offset должен быть равен нулю (все остальные значения не поддерживаются).
Возвращает новую абсолютную позицию как непрозрачное число.
Добавлено в версии 3.1: Константы SEEK_* .
Возвращает текущую позицию в потоке как непрозрачное число. Число обычно не представляет собой количество байтов в базовом двоичном хранилище.
Записывает в поток строку s и возвращает количество записанных символов.
class io. TextIOWrapper ( buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False ) ¶
Буферизованный текстовый поток через двоичный поток BufferedIOBase . Он наследует TextIOBase .
encoding предоставляет имя кодировки, с помощью которой будет декодироваться или кодироваться поток. По умолчанию это locale.getpreferredencoding(False) .
errors — необязательная строка, указывающая, как должны обрабатываться ошибки кодирования и декодирования. Передайте ‘strict’ , чтобы вызвать исключение ValueError , если есть ошибка кодирования (у значения по умолчанию None тот же эффект), или передайте ‘ignore’ , чтобы игнорировать ошибки. (Обратите внимание, что игнорирование ошибок кодирования может привести к потере данных.) ‘replace’ вызывает вставку замещающего маркера (например, ‘?’ ) там, где есть искаженные данные. ‘backslashreplace’ вызывает замену искаженных данных escape-последовательностью с обратной косой чертой. При записи можно использовать ‘xmlcharrefreplace’ (заменить соответствующей ссылкой на символ XML) или ‘namereplace’ (заменить escape- последовательностями \N <. >). Любое другое имя обработки ошибок, зарегистрированное в codecs.register_error() , также является допустимым.
newline управляет обработкой окончаний строк. Может быть None , » , ‘\n’ , ‘\r’ и ‘\r\n’ . Работает следующим образом:
- При чтении ввода из потока, если newline — None , включён режим универсальный символ новой строки . Строки во входных данных могут заканчиваться на ‘\n’ , ‘\r’ или ‘\r\n’ , и они преобразуются в ‘\n’ перед возвратом вызывающей стороне. Если это » , включён универсальный режим новой строки, но окончания строк возвращаются вызывающей стороне непереведёнными. Если у него любое из других допустимых значений, строки ввода завершаются только данной строкой, а окончание строки возвращается вызывающей стороне в непереведённом виде.
- При записи вывода в поток, если newline — None , любые записанные символы ‘\n’ переводятся в системный разделитель строк по умолчанию, os.linesep . Если newline — » или ‘\n’ , перевод не выполняется. Если newline — любое другое допустимое значение, любые записанные символы ‘\n’ переводятся в данную строку.
Если line_buffering — True , flush() подразумевается, когда вызов write содержит символ новой строки или возврат каретки.
Если write_through — True , вызовы write() гарантированно не буферизуются: любые данные, записанные в объекте TextIOWrapper , немедленно обрабатываются в его базовый двоичный файл buffer.
Изменено в версии 3.3: Добавлен аргумент write_through.
Изменено в версии 3.3: По умолчанию encoding теперь locale.getpreferredencoding(False) вместо locale.getpreferredencoding() . Не меняйте временно кодировку локали с помощью locale.setlocale() , используйте текущую кодировку локали вместо кодировки, предпочитаемой пользователем.
TextIOWrapper предоставляет ряд атрибутов в дополнение к атрибутам TextIOBase и его родителям:
Включена ли буферизация строки.
Передаются ли записи немедленно в базовый двоичный буфер.
Добавлено в версии 3.7.
Изменить конфигурацию текстового потока, используя новые настройки для encoding, errors, newline, line_buffering и write_through.
Не указанные параметры сохраняют текущие настройки, за исключением того, что используется errors=’strict’ , когда указано encoding, но не указано errors.
Невозможно изменить кодировку или новую строку, если некоторые данные уже были прочитаны из потока. С другой стороны, изменение кодировки после записи возможно.
Метод выполняет неявную очистку потока перед установкой новых параметров.
Добавлено в версии 3.7.
Поток в памяти для текстового ввода-вывода. Текстовый буфер удаляется при вызове метода close() .
Начальное значение буфера можно установить, указав initial_value. Если перевод новой строки включён, новые строки будут закодированы как write() . Поток располагается в начале буфера.
Аргумент newline работает аналогично аргументу TextIOWrapper . По умолчанию в качестве концов строк рассматриваются только символы \n и не выполняется перевод новой строки. Если для newline установлено значение None , символы новой строки записываются как \n на всех платформах, но универсальное декодирование новой строки по-прежнему выполняется при чтении.
StringIO предоставляет следующий метод в дополнение к методам из TextIOBase и его родителей:
Возвращает str , содержащий всё содержимое буфера. Новые строки декодируются как read() , хотя позиция в потоке не изменяется.
Вспомогательный кодек, декодирующий символы новой строки для режима универсальный символ новой строки . Он наследует codecs.IncrementalDecoder .
Производительность¶
В этом разделе обсуждается производительность предоставленных реализаций ввода-вывода.
Двоичный ввод/вывод¶
За счёт чтения и записи только больших блоков данных, даже когда пользователь запрашивает один байт, буферизованный ввод-вывод скрывает любую неэффективность при вызове и выполнении небуферизованных процедур ввода-вывода операционной системы. Прирост зависит от ОС и типа выполняемого ввода-вывода. Например, в некоторых современных ОС (например, Linux) небуферизованный дисковый ввод-вывод может быть таким же быстрым, как и буферизованный ввод-вывод. Суть в том, что буферизованный ввод-вывод обеспечивает предсказуемую производительность независимо от платформы и устройства поддержки. Следовательно, почти всегда предпочтительнее использовать буферизованный ввод-вывод, а не небуферизованный ввод-вывод для двоичных данных.
Текстовый ввод/вывод¶
Текстовый ввод-вывод в двоичном хранилище (таком как файл) значительно медленнее, чем двоичный ввод-вывод в том же хранилище, потому что он требует преобразования между Юникодом и двоичными данными с использованием символьного кодека. Может стать заметным при обработке огромных объёмов текстовых данных, таких как большие файлы журналов. Кроме того, TextIOWrapper.tell() и TextIOWrapper.seek() работают довольно медленно из-за используемого алгоритма восстановления.
StringIO , однако, является встроенным юникод контейнером в памяти и будет демонстрировать скорость, аналогичную BytesIO .
Многопоточность¶
Объекты FileIO являются потокобезопасными в той степени, в которой оборачиваемые вызовы операционной системы (например, read(2) в Unix), также являются потокобезопасными.
Объекты с двоичной буферизацией (экземпляры BufferedReader , BufferedWriter , BufferedRandom и BufferedRWPair ) защищают свои внутренние структуры с помощью блокировки; поэтому их можно безопасно вызывать сразу из нескольких потоков.
Объекты TextIOWrapper не являются потокобезопасными.
Реентерабельность¶
Объекты с двоичной буферизацией (экземпляры BufferedReader , BufferedWriter , BufferedRandom и BufferedRWPair ) не реентерабельны. Хотя повторные вызовы не происходят в обычных ситуациях, они могут возникать при выполнении операций ввода-вывода в обработчике signal . Если поток пытается повторно ввести буферизованный объект, к которому он уже обращается, возникает RuntimeError . Обратите внимание, что это не запрещает другому потоку входить в буферный объект.
Вышеупомянутое неявно распространяется на текстовые файлы, поскольку функция open() помещает буферизованный объект в TextIOWrapper . Это включает стандартные потоки и, следовательно, также влияет на встроенную функцию print() .
Python IO Module: The Complete Practical Reference

Hello everyone! In today’s article, we’ll be looking at using the Python IO Module.
This module is quite useful when you want to perform file-related I/O operations (eg. file reading/writing)
While you can use the normal read() and write() methods to read/write to a file, this module gives us a lot more flexibility regarding these operations.
To understand more about this module, let’s take some examples.
Python IO Module
This module is a part of the standard library, so there’s no need to install it separately using pip.
To import the io module, we can do the following:
In the io module there are 2 common classes which are very useful for us:
- BytesIO -> I/O operations on byte data
- StringIO -> I/O operations on string data
We can access these classes using io.BytesIO and io.StringIO .
Let’s take a look at them one by one.
Python BytesIO Class
Here, we can keep our data in the form of bytes ( b» ). When we use io.BytesIO , the data is held in an in-memory buffer.
We can get an instance to the byte stream using the constructor:
Notice that we are passing a byte string (prefixed using b ).
Right now, bytes_stream is simply a handle to the byte stream.
To actually print the data inside the buffer, we need to use bytes_stream.getvalue() .
Here, getvalue() takes the value of the byte string from the handle.
Since the byte string \x0A is the ASCII representation of the newline (‘\n’), we get the following output:
Output
Now, it is always a good practice to close our buffer handle whenever we have done our work.
This is also to make sure that we free whatever memory we’ve allocated for the buffer.
To close the buffer, use:
Now let’s look at the StringIO class.
Python StringIO Class
Similar to io.BytesIO , the io.StringIO class can read string related data from a StringIO buffer.
We can read from the string buffer using string_stream.read() and write using string_stream.write() . This is very similar to reading / writing from a file!
We can print the contents using getvalue() .
Output
Since we are writing to the same buffer, the new contents will obviously overwrite the old one!
Reading from a StringIO buffer
Similar to writing, we can also read from a StringIO buffer using buffer.read() .
Output
As you can see, the contents are now inside the read buffer, which is printed using buffer.read() .
Reading a file using io
We can using the io.open() method to directly read from a file also, similar to reading from a file object.
Here, this module gives us the option of buffered vs non-buffered reading.
For example, the following will use a buffered read to read a file, by setting buffering = SIZE . If SIZE = 0, this will imply no buffering!
Suppose sample.txt has the following contents:
Output
As you can see, the file has been read successfully! Here, io will read the file using a buffer size of approximately 5 bytes.