<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN> <html> <head> <title>fcopy</title> </head> <body> <h1>fcopy</h1> <p> Копирует данные из одного канала в другой. </p> <pre> <strong>fcopy</strong> <em>inchan</em> <em>outchan</em> ?<em>-size</em> <em>size</em>? ?<em>-command</em> <em>callback</em>? </pre> <h2>ОПИСАНИЕ</h2> <p> Команда <strong>fcopy</strong> копирует данные из одного канала ввода - вывода, заданного идентификатором канала <em>inchan</em>, в другой канал ввода - вывода, заданный идентификатором канала <em>outchan</em>. Команда позволяет упростить буферизацию и избежать излишнего копирования в Tcl-системе ввода - вывода, а также избежать использования больших объемов памяти при копировании данных по таким медленным каналам, как сетевые соединения.</p> <p>Команда <strong>fcopy</strong> передает данные из канала <em>inchan</em>, пока не будет достигнут конец файла или не будет передано <em>size</em> байтов. Если аргумент <em>-size</em> не задан, передается весь файл. Если опция <em>-command</em> не задана, команда блокирует процесс до завершения копирования и возвращает число переданных байтов.</p> <p>При наличии аргумента <em>-command</em> команда <strong>fcopy</strong> работает в фоновом режиме. Она завершается немедленно, а команда <em>callback</em> вызывается позже, когда завершается процесс копирования. Команда <em>callback</em> вызывается с одним или двумя дополнительными аргументами, которые указывают число переданных байтов. Если при исполнении фонового процесса произошла ошибка, второй аргумент - строка описания ошибки. При фоновом выполнении копирования каналы <em>inchan</em> и <em>outchan</em> не обязательно открывать в неблокирующем режиме, команда <strong>fcopy</strong> выполнит это автоматически. Однако при этом необходимо организовать обработку событий, например, с помощью команды <a href=vwait.html><strong>vwait</strong></a> или используя Tk.</p> <p>Не допускается выполнение других операций ввода - вывода с теми же каналами во время фонового копирования. Если один из каналов во время копирования будет закрыт, процесс копирования будет прерван и вызова команды <em>callback</em> не произойдет. Если будет закрыт канал ввода данных, то все полученные данные, хранящиеся в очереди, будут выданы в выходной канал.</p> <p>Необходимо отметить, что канал <em>inchan</em> может стать открытым на чтение во время копирования. Все обработчики файловых событий во время фонового копирования должны быть выключены, чтобы они не создавали помех копированию. Любые попытки ввода - вывода с помощью обработчиков файловых событий будут завершены с ошибкой "канал занят".</p> <p>Команда <strong>fcopy</strong> преобразует символы конца строк в соответствии со значениями опций <em>-translation</em> для соответствующих каналов (см. описание команды <a href=fconfigure.html><strong>fconfigure</strong></a>). Преобразование означает, в частности, что число прочитанных и число переданных символов может отличаться. В синхронном режиме команда возвращает только число переданных в <em>outchan</em> канал символов. В фоновом режиме только это число подается на вход команды callback.</p> <h2>ПРИМЕРЫ</h2> <p> Первый пример показывает, как в фоновом режиме получить число переданных байтов. Конечно, это показательный пример, поскольку то же самое может быть сделано проще без использования фонового режима.</p> <pre> 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 </pre> <p>Второй пример показывает, как можно организовать копирование файла по фрагментам и проверять конец файла.</p> <pre> 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 </pre> <p>См. также <a href=eof.html><strong>eof</strong></a>(n), <a href= fblocked.html><strong>fblocked</strong></a>(n), <a href= fcopy.html><strong>fconfigure</strong></a>(n).</p> </body> </html>