fileevent
Имя
fileevent — Выполнить скрипт, когда канал становится читаемым или записываемымСинтаксис
fileevent channelId readable ?script?fileevent channelId writable ?script?
Описание
Эта команда используется для создания обработчиков событий файла. Обработчик событий файла — это связка между каналом и скриптом, такой, что скрипт оценивается всякий раз, когда канал становится читаемым или записываемым. Обработчики событий файлов чаще всего используются для получения данных из другого процесса на основе событий, чтобы получатель мог продолжать взаимодействовать с пользователем, ожидая прибытия данных. Если приложение вызывает gets или read на блокирующем канале, когда доступных входных данных нет, процесс заблокируется; до тех пор, пока не появятся входные данные, он не сможет обрабатывать другие события, поэтому для пользователя будет казаться, что он «зависает». С помощью fileevent процесс может определить, когда данные присутствуют, и вызвать gets или read только тогда, когда они не заблокируются.Аргумент channelId для fileevent относится к открытому каналу, такому как стандартный канал Tcl (stdin, stdout или stderr), результат вызова open или socket или результат команды создания канала, предоставленной расширением Tcl.
Если указан аргумент script, тогда fileevent создаёт новый обработчик событий: script будет оцениваться всякий раз, когда канал становится читаемым или записываемым (в зависимости от второго аргумента fileevent). В этом случае fileevent возвращает пустую строку. Обработчики событий readable и writable для файла независимы и могут создаваться и удаляться отдельно. Однако для файла в данный момент интерпретатора может быть не более одного обработчика readable и одного writable. Если fileevent вызывается, когда указанный обработчик уже существует в вызывающем интерпретаторе, новый скрипт заменяет старый.
Если аргумент script не указан, fileevent возвращает текущий скрипт для channelId или пустую строку, если его нет. Если аргумент script указан как пустая строка, то обработчик событий удаляется, так что скрипт не будет вызываться. Обработчик событий файла также автоматически удаляется всякий раз, когда его канал закрывается или его интерпретатор удаляется.
Канал считается читаемым, если доступны не прочитанные данные на базовом устройстве. Канал также считается читаемым, если в буфере ввода имеются непрочитанные данные, за исключением специального случая, когда последняя попытка чтения из канала была вызовом gets, который не смог найти полную строку в буфере ввода. Эта функция позволяет читать файл построчно в режиме без блокировки с использованием событий. Канал также считается читаемым, если на базовом файле или устройстве присутствует конец файла или состояние ошибки. Важно, чтобы script проверял эти условия и обрабатывал их соответствующим образом; например, если нет специальной проверки на конец файла, может произойти бесконечный цикл, где script не читает данные, возвращается и сразу же вызывается снова.
Канал считается записываемым, если по крайней мере один байт данных может быть записан в базовый файл или устройство без блокировки или если на базовом файле или устройстве присутствует состояние ошибки.
Управляемое событиями ввод-вывод лучше всего работает для каналов, которые были переведены в режим без блокировки с помощью команды fconfigure. В режиме блокировки команда puts может заблокироваться, если вы предоставите ей больше данных, чем может принять базовый файл или устройство, а команда gets или read заблокируется, если вы попытаетесь прочитать больше данных, чем доступно; читаемый базовый файл или устройство может даже не гарантировать, что блокирующее чтение [1] будет успешным (контрпримерами являются многобайтовые кодировки, преобразования сжатия или шифрования). Во всех таких случаях события не будут обрабатываться в то время, пока команды блокируются.
В режиме без блокировки puts, read и gets никогда не блокируются. См. документацию по отдельным командам для получения информации о том, как они обрабатывают блокирующие и неблокирующие каналы.
Проверку условия конца файла следует выполнять после любой попытки чтения данных канала. Флаг eof устанавливается, как только произошла попытка чтения конца данных, и проверка до этого чтения потребует запуска дополнительного события.
Скрипт для события файла выполняется на глобальном уровне (вне контекста любой процедуры Tcl) в интерпретаторе, в котором была вызвана команда fileevent. Если при выполнении скрипта произошла ошибка, то используется команда, зарегистрированная с помощью interp bgerror, для сообщения об ошибке. Кроме того, обработчик событий файла удаляется, если он когда-либо возвращает ошибку; это делается для предотвращения бесконечных циклов из-за ошибочных обработчиков.
Пример
В этой настройке GetData будет вызываться с каналом в качестве аргумента всякий раз, когда $chan становится читаемым. Вызов read прочитает все доступные в данный момент двоичные данные без блокировки. Здесь обработчик событий канала удаляется, когда возникает конец файла, чтобы избежать его постоянного вызова (см. выше). В качестве альтернативы канал может быть закрыт при этом условии.proc GetData {chan} {
set data [read $chan]
puts "[string length $data] $data"
if {[eof $chan]} {
fileevent $chan readable {}
}
}
fconfigure $chan -blocking 0 -encoding binary
fileevent $chan readable [list GetData $chan] Следующий пример демонстрирует использование gets для чтения данных, ориентированных на строки.
proc GetData {chan} {
if {[gets $chan line] >= 0} {
puts $line
}
if {[eof $chan]} {
close $chan
}
}
fconfigure $chan -blocking 0 -buffering line -translation crlf
fileevent $chan readable [list GetData $chan] Авторы
fileevent основан на команде addinput, созданной Марком Диекхансом.См. также
fconfigure, gets, interp, puts, read, Tcl_StandardChannels
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/fileevent.htm
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/fileevent.htm