Копирует данные из одного канала в другой.
fcopy inchan outchan ?-size size? ?-command callback?
Команда fcopy копирует данные из одного канала ввода - вывода, заданного идентификатором канала inchan, в другой канал ввода - вывода, заданный идентификатором канала outchan. Команда позволяет упростить буферизацию и избежать излишнего копирования в Tcl-системе ввода - вывода, а также избежать использования больших объемов памяти при копировании данных по таким медленным каналам, как сетевые соединения.
Команда fcopy передает данные из канала inchan, пока не будет достигнут конец файла или не будет передано size байтов. Если аргумент -size не задан, передается весь файл. Если опция -command не задана, команда блокирует процесс до завершения копирования и возвращает число переданных байтов.
При наличии аргумента -command команда fcopy работает в фоновом режиме. Она завершается немедленно, а команда callback вызывается позже, когда завершается процесс копирования. Команда callback вызывается с одним или двумя дополнительными аргументами, которые указывают число переданных байтов. Если при исполнении фонового процесса произошла ошибка, второй аргумент - строка описания ошибки. При фоновом выполнении копирования каналы inchan и outchan не обязательно открывать в неблокирующем режиме, команда fcopy выполнит это автоматически. Однако при этом необходимо организовать обработку событий, например, с помощью команды vwait или используя Tk.
Не допускается выполнение других операций ввода - вывода с теми же каналами во время фонового копирования. Если один из каналов во время копирования будет закрыт, процесс копирования будет прерван и вызова команды callback не произойдет. Если будет закрыт канал ввода данных, то все полученные данные, хранящиеся в очереди, будут выданы в выходной канал.
Необходимо отметить, что канал inchan может стать открытым на чтение во время копирования. Все обработчики файловых событий во время фонового копирования должны быть выключены, чтобы они не создавали помех копированию. Любые попытки ввода - вывода с помощью обработчиков файловых событий будут завершены с ошибкой "канал занят".
Команда fcopy преобразует символы конца строк в соответствии со значениями опций -translation для соответствующих каналов (см. описание команды fconfigure). Преобразование означает, в частности, что число прочитанных и число переданных символов может отличаться. В синхронном режиме команда возвращает только число переданных в outchan канал символов. В фоновом режиме только это число подается на вход команды callback.
Первый пример показывает, как в фоновом режиме получить число переданных байтов. Конечно, это показательный пример, поскольку то же самое может быть сделано проще без использования фонового режима.
proc Cleanup {in out bytes {error {}}} { global total set total close сlose if {[string length ]!= 0} { # error occurred during the copy } } #### Открыть файл на чтение set in [open ] #### Открыть сетевое соединение set out [socket ] #### Скопировать, по окончании копирования вызвать Cleanup fcopy -command [list Cleanup ] #### Ожидать завершения копирования vwait total
Второй пример показывает, как можно организовать копирование файла по фрагментам и проверять конец файла.
proc CopyMore {in out chunk bytes {error {}}} { global total done incr total if {([string length ]!= 0) || [eof ] { set done close close } else { fcopy -command [list CopyMore ] -size } } set in [open ] set out [socket ] #### Установить размер фрагмента для копирования. set chunk 1024 set total 0 fcopy -command [list CopyMore ] -size vwait done
См. также eof(n), fblocked(n), fconfigure(n).