fcopy - 1つのチャンネルから別のチャンネルへデータをコピーします。
fcopy inchan outchan ?-size size? ?-command callback?
fcopyコマンドはI/Oチャンネルinchan から別のI/Oチャンネルoutchan
へデータをコピーします。 fcopyコマンドは、ネッ
トワークソケットのようなTcl のI/Oシステムのバッファリングを借りて巨大なファイルを遅いコピー先にコピーしているときに、
多くのデータをメインメモリにバッファしたり、余計にコピーすることを防ぐことができます。
fcopyコマンドはinchanからのデータをファイル終了かsizeで指定したバイ
ト数になるまで処理します。 -size引数が与えられない場合コピーはファイル終了まで行われます。
inchanから読まれたデータはすべてoutchan
へコピーされます。 -commandオプションがなければ、fcopyはコピーが完了するまでブロックをします。戻り値はoutchanへ書かれたバイト数です。
-command引数はfcopyをバックグラウンドで実行させます。この場合fcopyコマンドは直ちに制御を戻し、コピーが完了した後でcallback
が呼び出されます。 callbackはいくつか追加的な引数とともに呼びだされます。引数はoutchanへ書かれたバイト数を示します。バックグラウンドでコピーが行われている間にエラーが発生した場合、2番目の引数はエラーに関連付けられているエラー文字列として返されます。バックグラウンドでコピーするときにinchanやoutchan
を非ブロックモードに設定する必要はありません。fcopyコマンドが自動的に処理しますが、vwaitコマンドかkを使ってイベントルー
プに入る必要があります。
バックグラウンドでfcopyしている期間ではinchanやoutchanへのI/O操作を行うことはできません。コピー実行中にinchanかoutchanのどちらかがクローズされてしまうと、コピーは中止されコマンドコールバックは作成されません。
inchanがクローズされると、すでにoutchanキューにコピーされているすべてのデータはoutchanに書き出されます。
inchanがバックグラウンドコピーの間に読み込み可能になることがあります。バックグラウンドでコピーをしている間はコ
ピーの妨害をさせないように、すべてのfileeventハンドラを停止させなければなりません。
fileeventハンドラによる入出力の試みは"channel
busy"エラーで返されます。
fcopyはinchanとoutchanの行終了シーケンスをそれぞれのチャンネルの
-translationオプションに従って変換します。 -translationオプションの詳細は
fconfigure のマニュアルを参照してください。つまり、この変換があるため、inchanから読まれたバイト数がoutchanへ書かれるバイト数と異なることがありえます。outchanへ書かれたバイト数だけが返されます。同期的なfcopyの場合は戻り値として返され、非同期的なfcopyの場合はコールバックの引数として返されます。
Fcopyは個々のチャネルに設定されたエンコーディングに従います。
fcopyは最初にinchanを内部UTF-8に変換します。その後、チャネルのエンコーディングに変換されます。-encodingオプションに関する詳細はfconfigureをご参照下さい。両方のチャネルが「バイナリ」をコード化するためにセットされている場合、変換は行われません。出力チャネルがエンコーディング「バイナリ」にセットされれば、システムはinchanを内部UTF-8コードで出力します。入力チャネルがエンコーディング「バイナリ」にセットされれば、システムは入力バイトが正当なUTF-8コードとみなし、これを出力エンコーディングに従って変換します。正当なUTF-8コードではないバイトについて、システムの動作は定義されていません。
下記使用例では、コールバックがコピーされたバイト数を取得する方法を示します。ここではアプリケーションをイベントループに入らせるためにvwaitを用っています。もちろん、この簡単化された例はコマンドコールバックとしてでなくでも、実行できます。
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
2番目の例では、複数個のコピーを行い、コマン
ドコールバックでファイル終了の確認を行います。
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
eof, fblocked, fconfigure
blocking, channel,
end of file, nonblocking, read,
translation
Copyright © 1993 The Regents of the University of California.
Copyright © 1994-1997 Sun Microsystems, Inc.
Copyright © 1995-1997 Roger E. Critchlow Jr.
|