fcopy

ReferenceTOPKeywords

コマンド名

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番目の引数はエラーに関連付けられているエラー文字列として返されます。バックグラウンドでコピーするときにinchanoutchan を非ブロックモードに設定する必要はありません。fcopyコマンドが自動的に処理しますが、vwaitコマンドかkを使ってイベントルー プに入る必要があります。

バックグラウンドでfcopyしている期間ではinchanoutchanへのI/O操作を行うことはできません。コピー実行中にinchanoutchanのどちらかがクローズされてしまうと、コピーは中止されコマンドコールバックは作成されません。 inchanがクローズされると、すでにoutchanキューにコピーされているすべてのデータはoutchanに書き出されます。 

inchanがバックグラウンドコピーの間に読み込み可能になることがあります。バックグラウンドでコピーをしている間はコ ピーの妨害をさせないように、すべてのfileeventハンドラを停止させなければなりません。 fileeventハンドラによる入出力の試みは"channel busy"エラーで返されます。

fcopyinchanoutchanの行終了シーケンスをそれぞれのチャンネルの -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.