<!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 $bytes close $in сlose $out if {[string length $error]!= 0} { # error occurred during the copy } } #### Открыть файл на чтение set in [open $file1] #### Открыть сетевое соединение set out [socket $server $port] #### Скопировать, по окончании копирования вызвать Cleanup fcopy $in $out -command [list Cleanup $in $out] #### Ожидать завершения копирования vwait total </pre> <p>Второй пример показывает, как можно организовать копирование файла по фрагментам и проверять конец файла.</p> <pre> proc CopyMore {in out chunk bytes {error {}}} { global total done incr total $bytes if {([string length $error]!= 0) || [eof $in] { set done $total close $in close $out } else { fcopy $in $out -command [list CopyMore $in $out $chunk] \ -size $chunk } } set in [open $file1] set out [socket $server $port] #### Установить размер фрагмента для копирования. set chunk 1024 set total 0 fcopy $in $out -command [list CopyMore $in $out $chunk]\ -size $chunk 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>