chanコマンドについて
Tcl8.5で入出力関係のコマンドが、chanコマンドに集約されました。
以下の表の# xxxxx のコマンドが左側のchanコマンドに追加されています。
chan blocked ; # fblocked chan close ; # close chan configure ; # fconfigure chan copy ; # fcopy chan eof ; # eof chan event ; # fileevent chan flush ; # flush chan gets ; # gets chan names ; # file channels chan puts ; # puts chan read ; # read chan seek ; # seek chan tell ; # tell chan truncate ; # ftruncate [非推奨] fblocked fconfigure fcopy fileevent file channels
非推奨になっているコマンドは今後、廃止になる可能性がある為、chanコマンドで書き換えができるよう選り分けることが勧められています。
ファイルのコピー
ファイルをコピーするプログラムを2つ紹介します。
※ファイルは前回の、str.txt を使用します。
[str.txt]
Hello! Hello! Good morning! Bye bye! Have a nice day! こんにちわ おはようございます。 バイバイ よい1日を!
readコマンドを使う方法
[サンプル] copy1.tcl
#!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" # ファイルをコピーする set fid1 [open str.txt r] set fid2 [open str.cp1.txt w] puts $fid2 [read -nonewline $fid1] close $fid1 close $fid2
[実行例]
$ ls str* str.txt $ ./copy1.tcl $ ls str* str.cp1.txt str.txt $ cat str.cp1.txt Hello! Hello! Good morning! Bye bye! Have a nice day! こんにちわ おはようございます。 バイバイ よい1日を!
fcopy(chan copy)コマンドを使う方法
[書式]
fcopy inChan outCchan ?-size size? ?-command callback? chan copy inChan outChan ?-size size? ?-command callback?
fcopyコマンドは、inChanから別のoutChanにデータをコピーします。
-sizeを指定しない場合、コピーはファイルの最後まで行われます。-sizeに指定するサイズは、2つのチャンネルが同じエンコーディングを使用している場合、サイズはバイトで、それ以外の場合は文字数です。
-commandを指定しない場合、fcopyはコピーが完了するまでブロックされ、outChanに書き込まれたバイト数または文字数を返します。
-commandを指定すると、fcopyはバックグラウンドで動作します。この場合、即座に戻り、callbackはコピーの完了後に呼び出されます。
callbackは、outChanに書き込まれたバイト数を示す1つまたは2つの追加の引数で呼び出されます。バックグラウンド・コピー中にエラーが発生した場合、2番目の引数はエラーに関連するエラー文字列です。
※ -size, -commandを使用した例はここでは紹介しません。
[サンプル] copy2.tcl
#!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" # ファイルをコピーする その2 set fid1 [open str.txt r] set fid2 [open str.cp2.txt w] fcopy $fid1 $fid2 close $fid1 close $fid2
[実行例]
$ ./copy2.tcl $ ls str* str.cp1.txt str.cp2.txt str.txt $ cat str.cp2.txt Hello! Hello! Good morning! Bye bye! Have a nice day! こんにちわ おはようございます。 バイバイ よい1日を!
fcopyコマンドの代わりにchanコマンドを使う場合は以下のようにします。
chan copy $fid1 $fid2
文字コードと改行コード
tclの内部では文字コードにUTF-8、改行コードはLFを採用していますが、入出力処理においての文字コードと改行コードは使用環境に自動的に合わせてくれます。
※ファイルの文字コードを自動的に変換してくれるという意味ではないです。
以下は主な環境で使われているパターンです。
Windows
文字コード:シフトJIS、改行コード:CR+LF(\r\n)
※正確には文字コード:CP932
UNIXライクなOS
文字コード:UTF-8、改行コード:LF(\n)
※古い環境では文字コード:EUCが使われている場合もあります。
Mac OS X
文字コード:UTF-8、改行コード:LF(\n)
旧Mac(OS 9 以前)
文字コード:シフトJIS、改行コード:CR(\r)
※正確には文字コード:MacJapanese
[補足]
CP932
マイクロソフトがShift_JISを独自に拡張した文字コード。よってCP932の文字コードで作成されたファイルの入出力にShift_JISを指定するとローマ数字など一部の文字で文字化けが発生します。
MacJapanese
アップルがShift_JISを独自に拡張した文字コード。よってCP932の文字コードで作成されたファイルの入出力にShift_JISを指定するとローマ数字など一部の文字で文字化けが発生します。
LF : Line Feed(改行:0x0a)
CR : Carriage Return(復帰:0x0d)
Tclで使用できる主なエンコードの名前
iso2022-jp: JIS shiftjis : SJIS euc-jp : EUC utf-8 : Unicode(UTF-8) cp932 : MS-SJIS macJapan : 旧MACのSJIS
Tclで使用できるエンコードの名前は以下のコマンドで確認できます。
$ tclsh % encoding names cp860 cp861 cp862 cp863 tis-620 cp864 cp865 cp866 gb12345 gb2312-raw cp949 cp950 cp869 dingbats ksc5601 macCentEuro cp874 macUkraine jis0201 gb2312 euc-cn euc-jp macThai iso8859-10 jis0208 iso2022-jp macIceland iso2022 iso8859-13 iso8859-14 jis0212 iso8859-15 cp737 iso8859-16 big5 euc-kr macRomania macTurkish iso2022-kr gb1988 macGreek ascii cp437 macRoman iso8859-1 iso8859-2 iso8859-3 macCroatian iso8859-4 koi8-r ebcdic iso8859-5 cp1250 macCyrillic iso8859-6 cp1251 macDingbats iso8859-7 koi8-u cp1252 iso8859-8 cp1253 iso8859-9 cp1254 cp1255 cp850 cp1256 cp932 identity cp1257 cp852 macJapan cp1258 shiftjis utf-8 cp855 cp936 symbol cp775 unicode cp857
Tclでは、文字コードと改行コードを使用環境に合わせてくれるので同じ環境で使用する限りは気にする必要はありませんが、他の環境へファイルを持っていったり、他の環境で使われていたファイルを読み込む場合は、文字コードを変換する必要が生じる事があります。
以下のサンプルは文字コードをUTF8→CP932に変更した新しいファイルを作るプログラムです。
[サンプル] enc.tcl
#!/bin/sh # the next line restarts using tclsh \ exec tclsh "$0" "$@" # utf-8 -> shiftjis(cp932) へ変更してコピーする set fid1 [open str.txt r] set fid2 [open str.sjis.txt w] fconfigure $fid2 -translation crlf -encoding cp932 puts $fid2 [read -nonewline $fid1] close $fid1 close $fid2
[実行例]
$ ./enc.tcl $ ls str* str.cp1.txt str.cp2.txt str.sjis.txt str.txt # そのまま表示させると文字化けする。 $ cat str.sjis.txt Hello! Hello! Good morning! Bye bye! Have a nice day! �����ɂ��� ���͂悤�������܂��B �o�C�o�C �悢1�����I # 改行コードがCRLFで保存されていることを確認。 $ file str.sjis.txt str.sjis.txt: Non-ISO extended-ASCII text, with CRLF line terminators # iconvで文字コードを変換して表示させる。 $ iconv -f CP932 -t UTF-8 str.sjis.txt Hello! Hello! Good morning! Bye bye! Have a nice day! こんにちわ おはようございます。 バイバイ よい1日を!
上のサンプルでは、str.sjis.txtへ出力する際に使用する文字コードと改行コードをfconfigureコマンドで変更しています。
これも、fconfigureコマンドの代わりにchanコマンドを使う場合は以下のようにします。
chan configure $fid2 -translation crlf -encoding cp932
iconvは比較的に新しいUNIXライクなOSであれば標準でインストールされていると思います。
次回は、ファイルを開く時のエラー処理について紹介します。
コメント