一般的に、UNIX, Windows, Macintoshは、それぞれ異なるファイル名規則を持っています。
例えば、UNIXのファイル名のセパレータは、スラッシュ(/)ですが、Windowsは、バックスラッシュ(\)で、Macintoshは、コロン(:)です。
Tclは、ネーティブ形式とUNIX形式のネーミングコンベンションを許すことでプラットフォームに依存しないファイルのパス名を扱うことができます。
つまり、どのプラットフォームでもUNIXスタイルのスラッシュ区切りのファイルのパス名を使えるのです。
# Windowsネーティブ形式 C:\Program Files\Application\Foo # Windows UNC形式 \\Host\Share\Foo # UNIX形式 C:/Program Files/Application/Foo |
実際には、WindowsとMacintoshは、ドライブ名という概念があるので考慮が必要です。
以下は、2つのファイルのタイムスタンプを比較する例です。
proc filechk {file1 file2} { set time1 [file mtime $file1] set time2 [file mtime $file2] if {$time1 > $time2} { return "$file1 の方が新しい" } elseif {$time1 < $time2} { return "$file2 の方が新しい" } else { return "両方同じ" } } filechk /bin/sh /bin/bash |
fileコマンドには以下のオプションがあります。
file atime name ?time? | ファイルの最終アクセス時間を10進数で返す。timeを指定するとアクセス時間を設定できます。 Windows FATファイルシステムは未サポートです。 |
file attributes name file attributes name ?option? file attributes name ?option value option value...? | プラットフォーム依存のファイル属性をフラグで返す。optionとvalueを指定すると、ファイル属性を設定できます。 UNIXプラットフォームには、-group, -owner, -permissionsオプションがあります。 Windowsプラットフォームには、-archive, -hideen, -readonly, -shortnameオプションがあります。 Macintoshプラットフォームには、-creator, -hidden, -readonly, -typeオプションがあります。 |
file channels ?pattern? | オープンされたファイルのチャネル名をリスト形式で返す。patternを指定するとパターンにマッチ名前だけを返す。 |
file copy ?-force? ?- -? source target file copy ?-force? ?- -? source ?soruce...? targetDir | ファイルまたはディレクトリをコピーする。-forceオプションはエラーを無視して強制的にコピーする。 |
file delete ?-force? ?- -? pathname ?pathname? | ファイルまたはディレクトリを削除する。-forceオプションは、ファイルまたはディレクトリが存在しなくても無視する。 |
file dirname name | ファイルのパス名から最後の要素を除いた名前を返す。 |
file executable name | ファイルがカレントユーザによって実行可能であれば1を返す。そうでなければ0を返す。 |
file exists name | ファイルが存在していれば1を返す。そうでなければ0を返す。 |
file extension name | ファイルの拡張子を返す。 |
file isdirectory name | パス名がデイレクトリであれば1を返す。そうでなければ0を返す。 |
file isfile name | パス名がファイルであれば1を返す。そうでなければ0を返す。 |
file join name ?name...? | 1つ以上のファイル名を結合したパス名を返す。 |
file lstat name varName | ファイルのステータスを変数に返す。varNameは配列変数として扱います。 シンボリックリンクが未サポートのプラットフォームでは、下記のfile statと同じ結果になります。 |
file mkdir dir ?dir...? | ディレクトリを作成する。 |
file mtime name ?time? | ファイルの最終更新時間を10進数で返す。timeを指定すると更新時間を設定できます。 |
file nativename name | パス名をネーティブ形式のパス名に変換して返す。 |
file owned name | ファイルがカレントユーザのオーナーであれば1を返す。そうでなければ0を返す。 |
file pathtype name | absolute, relative, volumerelativeのいずれかを返す。absoluteは絶対パス、relativeは相対パス、volumerelativeは、ドライブ相対を意味する。 |
file readable name | ファイルがカレントユーザによって読み込み可能であれば1を返す。そうでなければ0を返す。 |
file readlink name | ファイルがシンボリックリンクの場合、実体のファイル名を返す。 シンボリックリンクをサポートしていないプラットフォームでは未サポートです。 |
file rename ?-force? ?- -? source target file rename ?-force? ?- -? source ?soruce...? targetDir | ファイルまたはディレクトリの名前を変更する。-forceオプションはエラーを無視して強制的に変更する。 |
file rootname name | ファイルの拡張子とドット( . )を除いたパス名を返す。 |
file size name | ファイルのバイトサイズを返す。 |
file split name | パス名の要素を分割して返す。 |
file stat name varName | ファイルのステータスを変数に返す。varNameは配列変数として扱います。 |
file tail name | 最後のディレクトリセパレータの後の文字列を返す。 |
file type name | ファイルのタイプを返す。file, directory, characterSpecial, blockSpecial, fifo, link, socketのいずれか。 |
file volume | ドライブ名の一覧を返す。 |
file writable name | ファイルがカレントユーザによって書き込み可能であれば1を返す。そうでなければ0を返す。 |
open name ?access? ?permission? | ファイルまたはパイプをオープンしてチャネルIDを返す。 |
puts ?-nonewline? ?channel? string | 文字列を書き込む |
gets channel ?varname? | 1行を読み込む |
read channel ?numBytes? | バイト数分か全データを読み込む |
read -nonewline channel ?numBytes? | 全データを読み込み最後の\nを捨てる |
tell channel | 現在のシークオフセットを返す。 |
seek channel offset ?origin? | オフセット分シークする。originは、start, current, endのいずれか。 |
eof channel | ファイルの終わり(EOF)かどうかチェックする |
flush channel | 書き込みバッファをフラッシュする。 |
close channel | ファイルをクローズする。 |
fconfigure channel fconfigure channel name fconfigure channel name value ?name value...? | チャネルオプションの設定と参照をする。 |
fblock channel | 読み込みでブロックするかテストする。 |
fileevent channel readable ?script? fileevent channel writable ?script? | チャネルが読み込みまたは書き込み可能になった時にスクリプトを実行する。 |
fcopy inchan outchan ?-size size? ?-command script? | チャネル間でデータをコピーする。 |
ファイルを読み込んで表示する例です。
if [catch {open "./foo.txt" r} fd] { error "ファイルがオープンできません" } while {[gets $fd line] >= 0} { puts stdout $line } close $fd |
コマンドの出力をパイプ使って読み込んで表示する例です。
if [catch {open "|/bin/ls -l" r} fd] { error "パイプがオープンできません" } while {[gets $fd line] >= 0} { puts stdout $line } close $fd |
ファイル、パイプ、ソケットの入出力を非同期に行うことができます。
非同期に処理を行うことで、同時に他の処理ができます。
次の例は、パイプ入力中にStopボタンまたはESCキーが押されたら処理を中止します。
button .start -text Start -command start button .stop -text Stop -command stop text .text grid .start .stop -sticky we grid .text - -sticky wens proc start {} { global fd if [catch {open "|ls -lR /" r} fd] { error "パイプがオープンできません" } .text delete 1.0 end fileevent $fd readable async } proc stop {} { global fd catch {close $fd} .text insert end ***Stoped***\n .text see end } proc async {} { global fd if [eof $fd] { close $fd } else { gets $fd line .text insert end $line\n update .text see end } } bind . <Escape> stop |
ファイル入出力の際に改行コードとencodingを指定する例です。
# 日本語SJISコードのファイルを読み込んで日本語EUCコードのファイルを書き込む set fd1 [open "foo.txt" r] set fd2 [open "bar.txt" w] fconfigure $fd1 -translation crlf -encoding shiftjis fconfigure $fd2 -translation lf -encoding euc-jp while {[gets $fd1 line] > 0} { puts $fd2 $line } close $fd1 close $fd2 |