fcopy 命令从 inchan 传输数据直到文件结束或传输完 size 字节。如果没有给出 -size 参数,则复制持续到文件结束。从 inchan 读的所有数据都复制到 outchan。如果没有 -command 选项,在复制完成并返回写到 outchan 的字节数之前 fcopy 将阻塞。
-command 参数使 fcopy 在后台工作。在这种情况下它立即返回,并在复制完成时调用 callback。调用 callback 加上一个或两个额外的参数来指示有多少字节被写到了 outchan。在后台复制期间如果发生了一个错误,第二个参数是与错误相关联的错误字符串。使用后台复制不需要把 inchan 或 outchan 转换成非阻塞模式;fcopy 命令将自动关照这些。但是,需要使用 vwait 命令或使用 Tk 进入事件循环。
在后台复制期间不允许对 inchan 或 outchan 做其他 I/O 操作。如果在复制进行期间 inchan 或 outchan 中被关闭,停止当前的复制并且不做命令回调。如果 inchan 被关闭,则写出为 outchan 而排队(queue)的所有数据。
注意在一个命令复制期间 inchan 可以变成可读的。在一个后台复制期间你应该关闭任何 fileevent 句柄,这样这些句柄不与复制相触及(interfere)。通过一个 fileevent 句柄的任何 I/O 尝试将得到一个 "channel busy" 错误。
Fcopy 依据 inchan 和 outchan 的 -translation 选项来转换它们中的文件行结束序列。参见fconfigure 的手册条目来得到 -translation 选项的详情。转换意味着从 inchan 读到的字节数与写到 outchan.的字节数可能不同。只报告写到 outchan 中的字节数。要么作为同步的 fcopy 的返回值,要么作为给异步的 fcopy 的回调的参数。
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
第二个例子按块(chunk)复制并在命令回调中测试文件结束。
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
Copyright © 1993 The Regents of the University of California. Copyright © 1994-1997 Sun Microsystems, Inc. Copyright © 1995-1997 Roger E. Critchlow Jr.