Provided by: tcl8.6-doc_8.6.1-4ubuntu1_all bug


       fcopy - Copy data from one channel to another


       fcopy inchan outchan ?-size size? ?-command callback?


       The  fcopy  command  copies  data  from  one  I/O  channel, inchan to another I/O channel,
       outchan.  The fcopy command leverages the buffering in the Tcl I/O system to  avoid  extra
       copies  and  to  avoid  buffering too much data in main memory when copying large files to
       slow destinations like network sockets.

       The fcopy command transfers data from inchan until end of file or  size  bytes  have  been
       transferred. If no -size argument is given, then the copy goes until end of file.  All the
       data read from inchan is copied to outchan.  Without the  -command  option,  fcopy  blocks
       until the copy is complete and returns the number of bytes written to outchan.

       The  -command  argument  makes  fcopy  work  in  the  background.  In this case it returns
       immediately and the callback is invoked later when the copy completes.   The  callback  is
       called  with one or two additional arguments that indicates how many bytes were written to
       outchan.  If an error occurred during the background copy,  the  second  argument  is  the
       error  string  associated  with the error.  With a background copy, it is not necessary to
       put inchan or outchan into non-blocking  mode;  the  fcopy  command  takes  care  of  that
       automatically.   However,  it  is  necessary  to  enter  the event loop by using the vwait
       command or by using Tk.

       You are not allowed to do other I/O operations with inchan or outchan during a  background
       fcopy.   If either inchan or outchan get closed while the copy is in progress, the current
       copy is stopped and the command callback is not made.  If inchan is closed, then all  data
       already queued for outchan is written out.

       Note  that  inchan  can become readable during a background copy.  You should turn off any
       fileevent handlers during a background copy so those handlers do not  interfere  with  the
       copy.  Any I/O attempted by a fileevent handler will get a “channel busy” error.

       Fcopy translates end-of-line sequences in inchan and outchan according to the -translation
       option for these channels.  See the  manual  entry  for  fconfigure  for  details  on  the
       -translation  option.  The translations mean that the number of bytes read from inchan can
       be different than the number of bytes written  to  outchan.   Only  the  number  of  bytes
       written  to  outchan  is reported, either as the return value of a synchronous fcopy or as
       the argument to the callback for an asynchronous fcopy.

       Fcopy obeys the encodings and character translations configured  for  the  channels.  This
       means  that the incoming characters are converted internally first UTF-8 and then into the
       encoding of the channel fcopy writes to. See the manual entry for fconfigure  for  details
       on  the -encoding and -translation options. No conversion is done if both channels are set
       to encoding “binary” and have matching translations. If only the output channel is set  to
       encoding  “binary” the system will write the internal UTF-8 representation of the incoming
       characters. If only the input channel is set to encoding “binary” the system  will  assume
       that  the  incoming  bytes  are  valid  UTF-8 characters and convert them according to the
       output encoding. The behaviour  of  the  system  for  bytes  which  are  not  valid  UTF-8
       characters is undefined in this case.


       The first example transfers the contents of one channel exactly to another. Note that when
       copying one file to another, it is better to use file copy which also copies file metadata
       (e.g. the file access permissions) where possible.

              fconfigure $in -translation binary
              fconfigure $out -translation binary
              fcopy $in $out

       This  second  example  shows how the callback gets passed the number of bytes transferred.
       It also uses vwait to put the application into the event loop.  Of course, this simplified
       example could be done without the command callback.

              proc Cleanup {in out bytes {error {}}} {
                  global total
                  set total $bytes
                  close $in
                  close $out
                  if {[string length $error] != 0} {
                      # error occurred during the copy
              set in [open $file1]
              set out [socket $server $port]
              fcopy $in $out -command [list Cleanup $in $out]
              vwait total

       The third example copies in chunks and tests for end of file in the command callback.

              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 -size $chunk \
                              -command [list CopyMore $in $out $chunk]
              set in [open $file1]
              set out [socket $server $port]
              set chunk 1024
              set total 0
              fcopy $in $out -size $chunk \
                      -command [list CopyMore $in $out $chunk]
              vwait done


       eof(3tcl), fblocked(3tcl), fconfigure(3tcl), file(3tcl)


       blocking, channel, end of line, end of file, nonblocking, read, translation