chan
-
ИМЯ
- chan — Чтение, запись и управление каналами
- СИНТАКСИС
- ОПИСАНИЕ
-
chan blocked channelId
- chan close channelId ?direction?
- chan configure channelId ?optionName? ?value? ?optionName value?...
-
-blocking boolean
- -buffering newValue
- -buffersize newSize
- -encoding name
- -eofchar char
- -eofchar {inChar outChar}
- -translation mode
- -translation {inMode outMode}
-
auto
- binary
- cr
- crlf
- lf
- binary
- -buffering newValue
- chan close channelId ?direction?
-
chan read channelId numChars
- chan read channelId
-
start
- current
- end
- current
Имя
chan — Чтение, запись и управление каналамиСинтаксис
chan option ?arg arg ...?Описание
Эта команда предоставляет несколько операций для чтения из, записи в и иного управления открытыми каналами (такими, как были созданы с помощью команд open и socket или стандартных именованных каналов stdin, stdout или stderr, которые соответствуют стандартному вводу, выводу и потоку ошибок процесса соответственно). Option указывает, что нужно сделать с каналом; любое уникальное сокращение для option приемлемо. Допустимые опции:- chan blocked channelId
- Это проверяет, завершилась ли последняя операция ввода на канале с именем channelId неудачно, потому что это привело бы к блокировке процесса, и возвращает 1, если это произошло. В противном случае возвращает 0. Обратите внимание, что это возвращает 1 только тогда, когда канал настроен на неблокирующий режим; по умолчанию все каналы Tcl имеют блокировку включенной.
- chan close channelId ?direction?
- Закрыть и уничтожить канал с именем channelId. Обратите внимание, что это удаляет все существующие события файла, зарегистрированные на канале. Если аргумент direction (который должен быть read или write или любым их сокращением) присутствует, канал будет закрыт частично, так что он может перейти от чтение/запись к только запись или только чтение соответственно. Если канал только для чтения закрыт для чтения, это то же самое, что и полное закрытие канала, и соответственно аналогично для каналов только для записи. Без аргумента direction канал закрывается для чтения и записи (но только если эти направления в данный момент открыты). Ошибка происходит, если закрывается канал только для чтения для записи, или канал только для записи для чтения.
В рамках закрытия канала, все буферизованный вывод сбрасывается в устройство вывода канала (только если канал прекращает быть записываемым), любой буферизованный ввод отбрасывается (только если канал прекращает быть читаемым), закрывается базовая системная ресурс и channelId становится недоступным для дальнейшего использования (только если канал полностью закрывается).
Если канал блокирующий и канал прекращает быть записываемым, команда не возвращает результат, пока весь вывод не будет сброшен. Если канал неблокирующий и есть несброшенный вывод, канал остается открытым, и команда возвращает результат немедленно; вывод будет сброшен в фоновом режиме, и канал будет закрыт, когда все сбросы будут завершены.
Если channelId — блокирующий канал для командного конвейера, то chan close ждет завершения дочерних процессов.
Если канал совместно используется между интерпретаторами, то chan close делает channelId недоступным в вызывающем интерпретаторе, но не имеет других последствий, пока все интерпретаторы, которые используют канал, не закроют его. Когда последний интерпретатор, в котором зарегистрирован канал, вызывает chan close (или close), выполняются описанные выше действия по очистке. При частичном закрытии частичное закрытие канала применяется только к текущему представлению канала в текущем интерпретаторе, пока все каналы не закроют его в этом направлении (или полностью). См. команду interp для описания совместного использования каналов.
Каналы автоматически полностью закрываются при уничтожении интерпретатора и при выходе процесса. Каналы переключаются в блокирующий режим, чтобы гарантировать, что весь вывод корректно сброшен перед выходом процесса.
Команда возвращает пустую строку и может сгенерировать ошибку, если возникнет ошибка при сбросе вывода. Если команда в командном конвейере, созданном с помощью open, возвращает ошибку, chan close генерирует ошибку (аналогично команде exec.)
Обратите внимание, что частичное закрытие сокетов и командных конвейеров может иметь важные побочные эффекты, потому что они приводят к вызову shutdown() или close() базового системного ресурса, что может изменить, как другие процессы или системы реагируют на программу Tcl.
- chan configure channelId ?optionName? ?value? ?optionName value?...
- Запрос или установка параметров конфигурации канала с именем channelId.
Если аргументы optionName или value не заданы, команда возвращает список, содержащий чередующиеся имена и значения параметров канала. Если задан optionName, но не value, команда возвращает текущее значение указанного параметра. Если заданы одна или несколько пар optionName и value, команда устанавливает каждый из указанных параметров в соответствующее значение value; в этом случае возвращаемое значение — пустая строка.
Ниже описаны параметры, поддерживаемые для всех каналов. Кроме того, каждый тип канала может добавлять собственные параметры. См. описание команды создания каждого типа канала в руководстве для параметров, поддерживаемых этим типом канала. Например, см. запись в руководстве по команде socket для дополнительных параметров для сокетов и команду open для дополнительных параметров для последовательных устройств.
- -blocking boolean
- Параметр -blocking определяет, могут ли операции ввода-вывода на канале привести к неограниченному блокированию процесса. Значение параметра должно быть правильным булевым значением. Каналы обычно работают в режиме блокировки; если канал переведён в режим без блокировки, это повлияет на работу команд chan gets, chan read, chan puts, chan flush и chan close; см. документацию по этим командам для получения подробностей. Для корректной работы режима без блокировки приложение должно использовать цикл событий Tcl (например, вызывая Tcl_DoOneEvent или вызывая команду vwait).
- -buffering newValue
- Если newValue равно full, система ввода-вывода будет буферизировать вывод, пока внутренний буфер не заполнится или не будет вызвана команда chan flush. Если newValue равно line, система ввода-вывода автоматически очищает вывод канала при каждом выводе символа новой строки. Если newValue равно none, система ввода-вывода будет автоматически очищать вывод после каждой операции вывода. По умолчанию -buffering установлен в full, за исключением каналов, подключённых к устройствам, похожим на терминалы; для таких каналов начальное значение равно line. Кроме того, stdin и stdout изначально установлены в line, а stderr установлен в none.
- -buffersize newSize
- Newvalue должен быть целым числом; его значение используется для установки размера буферов в байтах, которые будут выделены для этого канала для хранения ввода или вывода. Newvalue должен быть числом не более одного миллиона, позволяя буферы размером до одного миллиона байтов.
- -encoding name
- Этот параметр используется для задания кодировки канала как одного из именованных кодировок, возвращаемых командой encoding names, или специального значения binary, чтобы данные можно было преобразовывать в Unicode и из Unicode для использования в Tcl. Например, для того, чтобы Tcl мог читать символы из японского файла в кодировке shiftjis и правильно обрабатывать и отображать содержимое, кодировка должна быть установлена в shiftjis. После этого при чтении из канала байты в японском файле будут преобразовываться в Unicode по мере чтения. Поддерживается и запись — при записи Tcl-строк в канал они автоматически преобразуются в указанную кодировку на выходе.
Если файл содержит только двоичные данные (например, изображение JPEG), кодировка канала должна быть настроена на binary. Tcl не будет присваивать интерпретацию данным в файле и просто будет читать или записывать сырые байты. Команда Tcl binary может использоваться для работы с этими данными в формате байтов. Обычно лучше установить параметр -translation на значение binary, когда вы хотите передавать двоичные данные, так как это выключает другие автоматические интерпретации байтов в потоке как таковых.
По умолчанию для вновь открытых каналов используется та же зависимая от платформы и локали системная кодировка, которая используется для взаимодействия с операционной системой, как возвращается командой encoding system.
- -eofchar char
- -eofchar {inChar outChar}
- Этот параметр поддерживает файловые системы DOS, которые используют Control-z (\x1a) в качестве маркера конца файла. Если char не является пустой строкой, то этот символ сигнализирует об окончании файла при его обнаружении во время ввода. Для вывода символ конца файла выводится при закрытии канала. Если char — пустая строка, то нет специального маркера конца файла. Для каналов чтения-записи двухелементный список указывает маркер конца файла для ввода и вывода соответственно. Для удобства при установке символа конца файла для канала чтения-записи вы можете указать одно значение, которое будет применяться как для чтения, так и для записи. При запросе символа конца файла для канала чтения-записи всегда будет возвращаться двухелементный список. Значение по умолчанию для -eofchar — пустая строка во всех случаях, за исключением файлов в Windows. В этом случае -eofchar равен Control-z (\x1a) для чтения и пустой строке для записи. Допустимый диапазон значений для -eofchar — \x01 - \x7f; попытка установить -eofchar на значение вне этого диапазона приведёт к ошибке.
- -translation mode
- -translation {inMode outMode}
- В скриптах Tcl конец строки всегда представляется одним символом новой строки (\n). Однако в реальных файлах и устройствах конец строки может представляться по-разному на разных платформах или даже для разных устройств на одной платформе. Например, в UNIX в файлах используются новые строки, в то время как последовательность возврат каретки-новая строка обычно используется в сетевых соединениях. При вводе (т.е. с помощью chan gets и chan read) система ввода-вывода Tcl автоматически преобразует внешнее представление конца строки в символы новой строки. При выводе (т.е. с помощью chan puts) система ввода-вывода преобразует новые строки во внешнее представление конца строки. Режим перевода по умолчанию, auto, автоматически обрабатывает все общие случаи, но параметр -translation предоставляет явный контроль над преобразованиями конца строки.
Значение, связанное с -translation, является единственным элементом для каналов только для чтения и только для записи. Для каналов чтения-записи значение представляет собой двухелементный список; режим перевода для чтения — первый элемент списка, а режим перевода для записи — второй элемент. Для удобства при настройке режима перевода для канала чтения-записи вы можете указать одно значение, которое будет применяться для чтения и записи. При запросе режима перевода канала чтения-записи всегда будет возвращаться двухелементный список. В настоящее время поддерживаются следующие значения:
- auto
- В качестве режима перевода ввода auto рассматривает любую из новой строки (lf), возврат каретки (cr) или возврат каретки, за которым следует новая строка (crlf) как представление конца строки. Представление конца строки может даже меняться от строки к строке, и все случаи переводятся в новую строку. В качестве режима перевода вывода auto выбирает специфичное для платформы представление; для сокетов на всех платформах Tcl выбирает crlf, для всех версий Unix — lf, а для различных версий Windows — crlf. Значение по умолчанию для -translation равно auto как для ввода, так и для вывода.
- binary
- Преобразования конца строки не выполняются. Это практически идентично режиму lf, за исключением того, что режим binary также устанавливает символ конца файла на пустую строку (что отключает его) и устанавливает кодировку на binary (что отключает фильтрацию кодировки). См. описание -eofchar и -encoding для получения дополнительной информации.
- cr
- Конец строки в базовом файле или устройстве представлен одним символом возврата каретки. В режиме cr система преобразует возвраты каретки в символы новой строки. В режиме вывода cr система преобразует символы новой строки в символы возврата каретки.
- crlf
- Конец строки в базовом файле или устройстве представлен символом возврата каретки, за которым следует символ новой строки. В режиме crlf система преобразует последовательности возврат каретки-новая строка в символы новой строки. В режиме вывода crlf система преобразует символы новой строки в последовательности возврат каретки-новая строка. Этот режим обычно используется на платформах Windows и в сетевых подключениях.
- lf
- Конец строки в базовом файле или устройстве представлен одним символом новой строки (перевода строки). В этом режиме преобразования не выполняются ни при вводе, ни при выводе. Этот режим обычно используется на платформах UNIX.
- chan copy inputChan outputChan ?-size size? ?-command callback?
- Скопировать данные из канала inputChan, который должен быть открыт для чтения, в канал outputChan, который должен быть открыт для записи. Команда chan copy использует буферизацию в системе ввода-вывода Tcl, чтобы избежать лишних копий и чрезмерного буферизации данных в оперативной памяти при копировании больших файлов на медленные устройства, такие как сетевые сокеты.
Команда chan copy передает данные из inputChan до конца файла или пока не будет передано size байтов или символов; size выражается в байтах, если оба канала используют одинаковую кодировку, и в символах в противном случае. Если аргумент -size не указан, копирование происходит до конца файла. Все данные, прочитанные из inputChan, копируются в outputChan. Без опции -command, команда chan copy блокируется до завершения копирования и возвращает количество байтов или символов (используя те же правила, что и для опции -size), записанных в outputChan.
Аргумент -command заставляет команду chan copy работать в фоновом режиме. В этом случае она возвращает немедленно, и callback вызывается позже, когда копирование завершится. callback вызывается с одним или двумя дополнительными аргументами, указывающими, сколько байтов было записано в outputChan. Если при фоновом копировании произошла ошибка, второй аргумент — это строка ошибки, связанная с ошибкой. При фоновом копировании нет необходимости помещать inputChan или outputChan в режим без блокировки; команда chan copy заботится об этом автоматически. Однако необходимо войти в цикл обработки событий, используя команду vwait или с помощью Tk.
Вам запрещено выполнять другие операции ввода-вывода с inputChan или outputChan во время фонового выполнения chan copy. Если inputChan или outputChan закрываются во время копирования, текущее копирование останавливается, и обратный вызов команды не выполняется. Если inputChan закрывается, все данные, уже поставленные в очередь для outputChan, записываются.
Обратите внимание, что inputChan может стать доступным для чтения во время фонового копирования. Вы должны отключить все обработчики событий chan event или fileevent во время фонового копирования, чтобы эти обработчики не мешали копированию. Любая попытка ввода-вывода обработчика chan event или fileevent получит ошибку «канал занят».
Chan copy преобразует последовательности конца строки в inputChan и outputChan в соответствии с опцией -translation для этих каналов (см. chan configure выше). Преобразования означают, что количество байтов, прочитанных из inputChan, может отличаться от количества байтов, записанных в outputChan. Сообщается только количество байтов, записанных в outputChan, либо в качестве возвращаемого значения синхронного chan copy, либо как аргумент обратного вызова для асинхронного chan copy.
Chan copy подчиняется кодировкам и преобразованиям символов, настроенным для каналов. Это означает, что входящие символы сначала преобразуются во внутреннее представление UTF-8, а затем в кодировку канала, в который chan copy записывает (см. chan configure выше для подробной информации об опциях -encoding и -translation). Преобразование не выполняется, если оба канала настроены на кодировку binary и имеют соответствующие преобразования. Если только выходной канал настроен на кодировку binary, система запишет внутреннее UTF-8 представление входящих символов. Если только входной канал настроен на кодировку binary, система предположит, что входящие байты являются допустимыми символами UTF-8 и преобразует их в соответствии с выходной кодировкой. Поведение системы для байтов, которые не являются допустимыми символами UTF-8, в этом случае не определено.
- chan create mode cmdPrefix
- Эта подкоманда создает новый канал уровня скрипта, используя префикс команды cmdPrefix в качестве своего обработчика. Любой такой канал называется отражённым каналом. Указанный префикс команды cmdPrefix должен быть непустым списком и должен предоставлять API, описанное в руководстве refchan. Дескриптор нового канала возвращается в качестве результата команды chan create, и канал открыт. Используйте close или chan close для удаления канала.
Аргумент mode указывает, открыт ли новый канал для чтения, записи или обоих. Он должен быть списком, содержащим любые строки “read” или “write”. Список должен содержать по крайней мере один элемент, так как канал, к которому нельзя ни написать, ни прочитать, не имеет смысла. Команда-обработчик нового канала должна поддерживать выбранный режим, иначе произойдёт ошибка.
Префикс команды выполняется в глобальном пространстве имен, в верхней части стека вызовов, после добавления аргументов, как описано в руководстве refchan. Разрешение команд происходит во время вызова. Переименование или удаление команды означает, что следующий вызов метода обработчика может завершиться неудачей, что приведёт к неудаче вызова команды канала, вызывающего обработчик. В зависимости от вызываемой подкоманды сообщение об ошибке может не объяснить причину этой неудачи.
Каждый канал, созданный с помощью этой подкоманды, знает, в каком интерпретаторе он был создан, и всегда выполняет свою команду обработчика только в этом интерпретаторе, даже если канал был разделен и/или перемещён в другой интерпретатор. Каждый отражённый канал также знает поток, в котором он был создан, и выполняет свою команду обработчика только в этом потоке, даже если канал был перемещен в другой поток. Для этого все вызовы обработчика перенаправляются в исходный поток путём публикации специальных событий в него. Это означает, что исходный поток (то есть поток, который выполнил команду chan create) должен иметь активный цикл обработки событий, т.е. он должен иметь возможность обрабатывать такие события. В противном случае поток, отправляющий их, будет бесконечно блокироваться. Может произойти тупиковая ситуация.
Обратите внимание, что это позволяет создавать канал, два конца которого находятся в двух разных потоках, предоставляя ориентированную на потоки связку между этими потоками. Другими словами, мы можем предоставить способ обычной потоковой коммуникации между потоками вместо необходимости отправки команд.
При удалении потока или интерпретатора удаляются и все каналы, созданные с помощью этой подкоманды и использующие этот поток/интерпретатор в качестве своей вычислительной базы, во всех интерпретаторах, с которыми они были разделены или в которые были перемещены, и в любом потоке, в который они были перенесены. Хотя это лишает других поток(ов) и/или интерпретатор(ов) возможности использовать канал, это невозможно избежать. Попытка использовать такой канал приведёт к генерации стандартной ошибки об неизвестных дескрипторах канала.
Эта подкоманда safe и доступна безопасным интерпретаторам. Хотя она обеспечивает выполнение произвольного кода Tcl, система также гарантирует, что код всегда выполняется в безопасном интерпретаторе.
- chan eof channelId
- Проверить, завершилась ли последняя операция ввода на канале с именем channelId из-за достижения конца потока данных, возвращая 1, если достигнут конец файла, и 0 в противном случае.
- chan event channelId event ?script?
- Настроить скрипт Tcl script как обработчик событий файла для вызова всякий раз, когда канал с именем channelId переходит в состояние, описанное event (которое должно быть либо readable, либо writable); только один такой обработчик может быть установлен на одно событие на один канал за раз. Если script пустая строка, текущий обработчик удаляется (это также происходит, если канал закрыт или удален интерпретатор). Если script опущено, возвращается текущий установленный скрипт (или пустая строка, если такой обработчик не установлен). Обработчик вызывается только если цикл обработки событий обрабатывается (например, через vwait или update).
Обработчик событий файла — это связь между каналом и скриптом, такая, что скрипт оценивается всякий раз, когда канал становится доступным для чтения или записи. Обработчики событий файла чаще всего используются для получения данных из другого процесса на основе событий, так что получатель может продолжать взаимодействовать с пользователем или с другими каналами, ожидая получения данных. Если приложение вызывает chan gets или chan read на блокирующем канале, когда нет доступных входных данных, процесс заблокируется; до тех пор, пока не поступят данные, он не сможет обрабатывать другие события, поэтому для пользователя будет казаться, что он «замерз». С помощью chan event процесс может определить наличие данных и вызвать chan gets или chan read только тогда, когда они не будут блокировать.
Канал считается доступным для чтения, если на базовом устройстве есть доступные непрочитанные данные. Канал также считается доступным для чтения, если есть непрочитанные данные в буфере ввода, за исключением специального случая, когда последняя попытка чтения из канала была вызовом chan gets, который не смог найти полную строку в буфере ввода. Эта функция позволяет читать файл по одной строке за раз в режиме без блокировки с использованием событий. Канал также считается доступным для чтения, если присутствует конец файла или состояние ошибки на базовом файле или устройстве. Важно, чтобы script проверял эти условия и обрабатывал их соответствующим образом; например, если нет специальной проверки на конец файла, может возникнуть бесконечный цикл, где script не считывает данные, возвращается и немедленно вызывается снова.
Канал считается доступным для записи, если хотя бы один байт данных можно записать в базовом файле или устройстве без блокировки или если на базовом файле или устройстве присутствует состояние ошибки. Обратите внимание, что клиентские сокеты, открытые в асинхронном режиме, становятся доступными для записи, когда они соединяются или если соединение прерывается.
Управляемый событиями ввод-вывод лучше всего работает для каналов, помещенных в режим без блокировки с помощью команды chan configure. В режиме блокировки команда chan puts может заблокироваться, если вы передадите ей больше данных, чем может принять базовое устройство файла, а команда chan gets или chan read заблокируется, если вы попытаетесь прочитать больше данных, чем доступно; пока команды блокируются, другие события не будут обрабатываться. В режиме без блокировки команды chan puts, chan read и chan gets никогда не блокируются.
Скрипт обработчика события файла выполняется на глобальном уровне (вне контекста любой Tcl-процедуры) в интерпретаторе, в котором была вызвана команда chan event. Если при выполнении скрипта возникает ошибка, используется команда, зарегистрированная с помощью interp bgerror, для отчёта об ошибке. Кроме того, обработчик событий файла удаляется, если он когда-либо возвращает ошибку; это делается для предотвращения бесконечных циклов из-за ошибочных обработчиков.
- chan flush channelId
- Обеспечивает, что весь ожидающий вывод для канала с именем channelId будет записан.
Если канал находится в режиме блокировки, команда не возвращает управление, пока весь буферизованный вывод не будет отправлен в канал. Если канал находится в режиме без блокировки, команда может вернуть управление, прежде чем весь буферизованный вывод будет отправлен; оставшаяся часть будет отправлена в фоновом режиме с максимальной скоростью, которую поддерживает соответствующий файл или устройство.
- chan gets channelId ?varName?
- Читает следующую строку из канала с именем channelId. Если varName не указано, результатом команды будет прочитанная строка (без заключительного символа новой строки) или пустая строка при достижении конца файла или, в режиме без блокировки, если доступные данные исчерпаны. Если varName указано, прочитанная строка будет записана в переменную с именем varName, а результатом будет количество прочитанных символов или -1, если был достигнут конец файла или, в режиме без блокировки, если доступные данные исчерпаны.
Если конец файла встречается в процессе чтения строки, частичная строка будет возвращена (или записана в varName). Когда varName не указано, случай конца файла можно отличить от пустой строки с помощью команды chan eof, а случай частичной строки, но без блокировки, можно отличить с помощью команды chan blocked.
- chan names ?pattern?
- Выводит список всех имён каналов. Если pattern указано, будут возвращены только те имена каналов, которые соответствуют ему (в соответствии с правилами соответствия строк string match).
- chan pending mode channelId
- В зависимости от того, mode равно input или output, возвращает количество байтов входных или выходных (соответственно) данных, в настоящее время буферизованных внутри для channelId (особенно полезно в обратном вызове событий для чтения, чтобы наложить прикладные ограничения на длину строк ввода, чтобы избежать потенциальной атаки типа «отказ в обслуживании», где вредоносный пользователь создаёт чрезвычайно длинную строку, превышающую доступную память для её буферизации). Возвращает -1, если канал не был открыт для указанного режима.
- chan pipe
- Создаёт автономную трубу, чьи каналы чтения и записи возвращаются в виде списка из 2 элементов, первый элемент — сторона чтения, второй — сторона записи. Может быть полезен, например, для отдельного перенаправления stderr и stdout из дочернего процесса. Для этого следует запустить с операторами перенаправления "2>@" или ">@" на сторону записи трубы, а затем немедленно закрыть её в родительском процессе. Это необходимо, чтобы получить EOF на стороне чтения, как только дочерний процесс завершит работу или иначе закроет свой вывод.
Обратите внимание, что семантика буферизации труб может существенно различаться на уровне операционной системы; нельзя предполагать, что запись, выполненная на стороне вывода трубы, мгновенно появится на стороне ввода. Это фундаментальное различие, и Tcl не может его скрыть. Общие семантики потоков совместимы, поэтому блокирующие чтения и записи не увидят большинство различий, но детали того, что именно записывается, не учитываются. Это наиболее вероятно проявится при использовании труб для тестирования; необходимо принять меры для предотвращения тупиковых ситуаций и обеспечения возможности кратких чтений.
- chan pop channelId
- Удаляет верхний преобразователь из канала channelId, если он есть. Если к channelId не добавлены преобразователи, это эквивалентно команде chan close для этого канала. Результатом обычно является пустая строка, но в некоторых ситуациях может быть ошибка (например, если закрыт базовый поток системы и это приводит к ошибке).
- chan postevent channelId eventSpec
- Эта подкоманда используется обработчиками команд, определёнными с помощью chan create. Она уведомляет канал, представленный дескриптором channelId, о том, что произошли события, перечисленные в eventSpec. Аргумент должен быть списком, содержащим любые из строк read и write. Список должен содержать как минимум один элемент, так как вызов команды не имеет смысла, если не происходит никаких событий.
Обратите внимание, что эту подкоманду можно использовать только с дескрипторами каналов, созданными/открытыми с помощью chan create. Все остальные каналы приведут к сообщению об ошибке.
Поскольку только уровень Tcl канала, т. е. его обработчик команд, должен публиковать события, мы также ограничиваем использование этой команды интерпретатором, который создал канал. Другими словами, публикация событий в отражённом канале из интерпретатора, который не содержит его реализацию, не допускается. Попытка публикации события из любого другого интерпретатора приведёт к сообщению об ошибке.
Ещё одно ограничение заключается в том, что невозможно публиковать события, к которым ядро ввода-вывода не проявило интереса. Попытка сделать это приведёт к ошибке. См. метод обработчика команд watch, описанный в refchan, документе, описывающем API обработчиков команд для отражённых каналов.
Эта команда safe и доступна для безопасных интерпретаторов. Она может запускать обработчики chan event, как в текущем интерпретаторе, так и в других интерпретаторах или других потоках, даже когда событие опубликовано из безопасного интерпретатора, и его ждёт доверенный интерпретатор. Обработчики Chan event всегда выполняются в интерпретаторе, который их настроил.
- chan push channelId cmdPrefix
- Добавляет новый преобразователь поверх канала channelId. Аргумент cmdPrefix описывает список одного или нескольких слов, которые представляют обработчик, который будет использоваться для реализации преобразования. Префикс команды должен предоставить API, описанный в руководстве transchan. Результатом этой подкоманды является дескриптор преобразователя. Обратите внимание, что важно убедиться, что преобразование способно поддерживать режим канала, с которым оно используется, иначе канал может быть ни читаемым, ни записываемым.
- chan puts ?-nonewline? ?channelId? string
- Записывает string в канал с именем channelId, за которым следует символ новой строки. Заключительный символ новой строки записывается, если не указан необязательный флаг -nonewline. Если channelId опущен, строка записывается в стандартный выходной канал, stdout.
Символы новой строки в выводе переводятся командой chan puts в последовательности символов конца строки, специфичные для платформы, в соответствии с текущим значением опции -translation для канала (например, в системах PC новые строки обычно заменяются последовательностями возврат каретки-перевод строки; см. chan configure выше для получения подробностей).
Tcl буферизует вывод внутри, поэтому символы, записанные с помощью chan puts, могут не появиться немедленно в файле или устройстве вывода; Tcl обычно откладывает вывод до заполнения буфера или закрытия канала. Вы можете принудительно заставить вывод появиться немедленно с помощью команды chan flush.
Когда буфер вывода заполняется, команда chan puts обычно блокируется, пока все буферизованные данные не будут приняты для вывода операционной системой. Если channelId находится в режиме без блокировки, то команда chan puts не будет блокироваться, даже если операционная система не может принять данные. Вместо этого Tcl продолжает буферизовать данные и записывает их в фоновом режиме с максимальной скоростью, с которой это поддерживается файлом или устройством. Приложение должно использовать цикл событий Tcl для работы с выводом без блокировки; в противном случае Tcl никогда не узнает, что файл или устройство готовы к получению дополнительных данных вывода. Возможно, что для канала в режиме без блокировки будет буферизовано произвольно большое количество данных, что может потребовать значительного объёма памяти. Чтобы избежать потери памяти, ввод-вывод без блокировки обычно должен использоваться в режиме событий с помощью команды chan event (не вызывайте chan puts, если вы недавно не получили уведомление через событие файла, что канал готов к приёму дополнительных данных вывода).
- chan read channelId ?numChars?
- chan read ?-nonewline? channelId
- В первом формате результатом будут следующие numChars символов, считанных из канала с именем channelId; если numChars опущено, считываются все символы до момента, когда канал сигнализирует об ошибке (независимо от того, конец файла, блокировка или другое условие ошибки). Во втором формате (т. е. когда numChars опущено) флаг -nonewline может быть задан, чтобы указать, что любая заключительная новая строка в считанной строке должна быть обрезана.
Если channelId находится в режиме без блокировки, chan read может не прочитать столько символов, сколько запрошено: как только все доступные данные будут считаны, команда вернёт доступные данные, вместо того чтобы блокироваться, ожидая дополнительных данных ввода. Если канал настроен на использование кодировки с несколькими байтами, то фактически могут остаться некоторые байты в внутренних буферах, которые не образуют целого символа. Эти байты не будут возвращены, пока не будет доступен целый символ или не будет достигнут конец файла. Переключатель -nonewline игнорируется, если команда возвращается, прежде чем достичь конца файла.
Chan read переводит последовательности символов конца строки в символы новой строки в соответствии с опцией -translation для канала (см. chan configure выше для обсуждения способов, которыми chan configure изменит входные данные).
При чтении из последовательного порта большинство приложений должны настроить канал последовательного порта на режим без блокировки, например так:
chan configure channelId -blocking 0.
Затем chan read ведёт себя примерно так, как описано выше. Обратите внимание, что большинство последовательных портов сравнительно медленные; вполне возможно получить событие readable для каждого прочитанного символа. Необходимо проявлять осторожность при использовании chan read для блокирующих последовательных портов:
- chan read channelId numChars
- В этом формате chan read блокируется, пока не будет получено numChars символов из последовательного порта.
- chan read channelId
- В этом формате chan read блокируется, пока не будет получен символ конца файла, см. chan configure -eofchar. Если для канала не настроен символ конца файла, то chan read будет блокироваться вечно.
- chan seek channelId offset ?origin?
- Устанавливает текущую позицию доступа в потоке данных для канала с именем channelId на offset байтов относительно origin. Offset должен быть целым числом (может быть отрицательным), а origin должен быть одним из следующих:
- start
- Новая позиция доступа будет на offset байтов от начала подлежащего файла или устройства.
- current
- Новая позиция доступа будет на offset байтов от текущей позиции доступа; отрицательное offset перемещает позицию доступа назад в подлежащий файл или устройство.
- end
- Новая позиция доступа будет на offset байтов от конца файла или устройства. Отрицательное offset помещает позицию доступа перед концом файла, а положительное offset — после конца файла.
-
Аргумент origin по умолчанию равен start.
Chan seek очищает все буферизованный вывод для канала перед возвращением команды, даже если канал находится в режиме без блокировки. Он также отбрасывает любые буферизованные и непрочитанные данные. Эта команда возвращает пустую строку. Возникает ошибка, если эта команда применяется к каналам, чьи подлежащие файлы или устройства не поддерживают позиционирование.
Обратите внимание, что значения offset — это смещения в байтах, а не в символах. Как chan seek, так и chan tell работают в байтах, а не в символах, в отличие от chan read.
- chan tell channelId
- Возвращает число, представляющее текущую позицию доступа в потоке данных для канала с именем channelId. Это возвращаемое значение — смещение в байтах, которое может быть передано в chan seek для установки канала в определённую позицию. Обратите внимание, что это значение выражено в байтах, а не в символах, как в chan read. Для каналов, которые не поддерживают позиционирование, возвращается значение -1.
- chan truncate channelId ?length?
- Устанавливает длину подлежащего потока данных для канала с именем channelId на length (или на текущее смещение в байтах в подлежащем потоке данных, если length опущено). Канал сбрасывается перед усечением.
Примеры
Этот пример открывает файл с известным кодированием (CP1252, очень распространённое кодирование в Windows), ищет строку, переписывает эту часть и усекает файл после ещё двух строк.set f [open somefile.txt r+]
chan configure $f -encoding cp1252
set offset 0
# Search for string "FOOBAR" in the file
while {[chan gets $f line] >= 0} {
set idx [string first FOOBAR $line]
if {$idx > -1} {
# Found it; rewrite line
chan seek $f [expr {$offset + $idx}]
chan puts -nonewline $f BARFOO
# Skip to end of following line, and truncate
chan gets $f
chan gets $f
chan truncate $f
# Stop searching the file now
break
}
# Save offset of start of next line for later
set offset [chan tell $f]
}
chan close $f Сервер сети, выполняющий эхо-отражение вводимой строки по строкам без предотвращения обслуживания других подключений одновременно.
# This is a very simple logger...
proc log {message} {
chan puts stdout $message
}
# This is called whenever a new client connects to the server
proc connect {chan host port} {
set clientName [format <%s:%d> $host $port]
log "connection from $clientName"
chan configure $chan -blocking 0 -buffering line
chan event $chan readable [list echoLine $chan $clientName]
}
# This is called whenever either at least one byte of input
# data is available, or the channel was closed by the client.
proc echoLine {chan clientName} {
chan gets $chan line
if {[chan eof $chan]} {
log "finishing connection from $clientName"
chan close $chan
} elseif {![chan blocked $chan]} {
# Didn't block waiting for end-of-line
log "$clientName - $line"
chan puts $chan $line
}
}
# Create the server socket and enter the event-loop to wait
# for incoming connections...
socket -server connect 12345
vwait forever См. также
close, eof, fblocked, fconfigure, fcopy, file, fileevent, flush, gets, open, puts, read, seek, socket, tell, refchan, transchan
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/chan.htm
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/chan.htm