<!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> может стать
      открытым на чтение во время копирования. Все обработчики
      файловых событий во время фонового копирования должны быть
      выключены, чтобы они не создавали помех копированию. Любые
      попытки ввода - вывода с помощью обработчиков файловых событий
      будут завершены с ошибкой &quot;канал занят&quot;.</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>