# Класс *io_stream* Класс, предназначенный для работы с потоками ## Содержание - [Режимы](#режимы) - [general](#general) - [flush](#flush) - [binary](#binary) - Методы - [режимы и их состояния](#методы-режимов-и-их-состояний) - [I/O](#io-методы) - [Buffered-методы](#методы-buffered-режима) - [Методы потока](#методы-контроля-состояния-потока) ## Режимы Поток имеет три различных вида режима: - Режим общего поведения (`general` / `mode`) - Режим сброса (`flush` / `flush_mode`) - Двоичный режим (`binary`) ### general Определяет, как поток обрабатывает чтение и запись, имеет три подрежима: | Режим | Описание | |---------------|-------------------------------------------------------------------------------------------------------------------------------------------------| | `"default"` | Прямой режим. `read` может вернуть меньше байт, чем запрошено. `write` сразу отправляет данные в низкоуровневый дескриптор. Нет буферизации. | | `"yield"` | Как `default`, но при нехватке данных в `read(n)` поток будет вызывать `coroutine.yield()`, пока не соберёт ровно `n` байт. Удобно для корутин. | | `"buffered"` | Включает внутренние буферы чтения и записи. `read` берёт данные из буфера , `write` — складывает в буфер. | ### flush Работает только в режиме `"buffered"`, имеет два подрежима: | Режим | Что делает `flush()` | |------------------------|-----------------------------------------------------------------------------------------------------| | `"all"` (по умолчанию) | Сначала сбрасывает буфер записи → низкоуровневый `write`, затем вызывает `io_lib.flush(descriptor)` | | `"buffer"` | Сбрасывает только буфер записи, без вызова системного `flush` | ### binary **Независимый флаг** (включается через `set_binary_mode(true)` или при создании потока). Определяет, в каком виде методы `read` и `write` принимают и возвращают данные: | binary = true | binary = false (по умолчанию) | |------------------------------------------------------------|----------------------------------------| | Данные — это **байты** (`Bytearray`, таблица чисел 0..255) | Данные — это **текстовые строки** | | `read(n)` → `Bytearray` или `table` | `read()` → одна строка | | `read("i4 f")` → распаковка через `byteutil.unpack` | `read(n)` → n строк в таблице | | `write(Bytearray)` → запись байтов | `write("hello")` → строка + `\n` | | `write("i4", 42)` → `byteutil.pack` | `write({"a","b"})` → две строки с `\n` | `read_line` / `write_line` — работают как в текстовом режиме > [!WARNING] > Важно: даже в `binary = true` методы `read_line()` и `write_line()` остаются текстовыми — они всегда работают со строками. ## Методы режимов и их состояний ```lua -- Возвращает true, если поток используется в двоичном режиме io_stream:is_binary_mode() -> boolean -- Включает или выключает двоичный режим io_stream:set_binary_mode(boolean) -- Возвращает режим работы потока io_stream:get_mode() -> string -- Задаёт режим работы потока. Выбрасывает ошибку, если передан неизвестный режим io_stream:set_mode(string) -- Возвращает режим работы flush io_stream:get_flush_mode() -> string -- Задаёт режим работы flush io_stream:set_flush_mode(string) ``` ## I/O методы ```lua --[[ Читает данные из потока В двоичном режиме: Если arg - int, то читает из потока arg байт и возвращает ввиде Bytearray или таблицы, если use_table = true Если arg - string, то функция интерпретирует arg как шаблон для byteutil. Прочитает кол-во байт, которое определено шаблоном, передаст их в byteutil.unpack и вернёт результат В текстовом режиме: Если arg - int, то читает нужное кол-во строк с окончанием CRLF/LF из arg и возвращает ввиде таблицы. Также, если trim_empty_lines = true, то удаляет пустые строки с начала и конца из итоговой таблицы Если arg не определён, то читает одну строку с окончанием CRLF/LF и возвращает её. --]] io_stream:read( [опционально] arg: int | string, [опционально] use_table = false | trim_empty_lines = true: boolean ) -> Bytearray | table | string | table | ... --[[ Записывает данные в поток В двоичном режиме: Если arg - string, то функция интерпретирует arg как шаблон для byteutil, передаст его и ... в byteutil.pack и результат запишет в поток Если arg - Bytearray | table, то записывает байты в поток В текстовом режиме: Если arg - string, то записывает строку в поток (вместе с окончанием LF) Если arg - table, то записывает каждую строку из таблицы отдельно --]] io_stream:write( arg: Bytearray | table | string | table, [опционально] ... ) -- Читает одну строку с окончанием CRLF/LF из потока вне зависимости от двоичного режима io_stream:read_line() -> string -- Записывает одну строку с окончанием LF в поток вне зависимости от двоичного режима io_stream:write_line(string) --[[ В двоичном режиме: Читает все доступные байты из потока и возвращает ввиде Bytearray или table, если use_table = true В текстовом режиме: Читает все доступные строки из потока в table если use_table = true, или в одну строку вместе с окончаниями, если нет --]] io_stream:read_fully( [опционально] use_table: boolean ) -> Bytearray | table | table | string --[[ Если length определён, то возвращает true, если length байт доступно к чтению. Иначе возвращает false. Если не определён, то возвращает количество байт, которое можно прочитать. В не буферизированном режиме потока может всегда возвращать 0 или false, если поток не поддерживает available. --]] io_stream:available( [опционально] length: int ) -> int | boolean --[[ Устанавливает позицию в потоке (всегда в байтах) Режимы: b - Задаёт позицию относительно начало файла c - Задаёт позицию относительно текущей позиции e - Задаёт позицию относительно конца файла Может бросать ошибку, если поток не поддерживает seek. --]] io_stream:seek( mode: string offset: int ) -- Возвращает текущую позицию в потоке от начала. -- Может бросать ошибку, если поток не поддерживает tell. io_stream:tell() -> int ``` ## Методы Buffered-режима ```lua -- Возвращает максимальный размер буферов io_stream:get_max_buffer_size() -> int -- Задаёт новый максимальный размер буферов io_stream:set_max_buffer_size(max_size: int) ``` ## Методы контроля состояния потока ```lua -- Возвращает true, если поток открыт на данный момент io_stream:is_alive() -> bool -- Возвращает true, если поток закрыт на данный момент io_stream:is_closed() -> bool -- Закрывает поток io_stream:close() -- Записывает все данные из write-буфера в поток в buffer/all flush-режимах -- Вызывает ioLib.flush() в all flush-режиме, или ничего не делает, если -- ioLib не поддерживает flush. io_stream:flush() -- Создаёт новый поток из Bytearray. -- Может использоваться одновременно как для чтения, так и для записи. -- Результат записи будет записан в тот же Bytearray, что был передан в функцию. io_stream.wrap_bytearray( buffer: Bytearray, -- по-умолчанию равен true, поскольку функция из вводных аргументов -- будет использоваться преимущественно для работы с двоичными данными. [опционально] binary_mode: boolean = true ) -> io_stream -- Создаёт новый поток с переданным дескриптором и использующим переданную I/O библиотеку. (Более подробно в core:io_stream.lua) io_stream.new( descriptor: int, binary_mode: boolean, io_lib: table, [опционально] mode: string = "default", [опционально] flush_mode: string = "all" ) -> io_stream ```