Tcl – ファイルの入出力(1) 基本操作

ファイルの入出力

これまで紹介したプログラムは、標準入力(キーボード)から読み込み、標準出力(画面)へ出力するものでした。標準入出力については、「文字列の入力と出力について」で紹介しました。

この入出力処理をファイルに対して行うことで、計算結果などのデータをファイルに保存したり、ファイルに保存したデータを読み込んで処理を行う、といった事ができるようになります。

ファイルの作成・書込み・読込みといったファイルアクセスに関連する操作をTclで行うには、どのようにすればいいのか、次の項目で説明します。

ファイルの作成・書込み・読込みのやり方

Tclでファイルにアクセスするには、どのような記述を行えばいいのか、まずはサンプルコードを見て頂いた後に、1つ1つ説明していくようにします。

[サンプル] rw.tcl

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

# ファイルの作成と文字列の書き込み
proc WriteString {str} {
    set fid [open str.txt w ]
    puts $fid "$str"
    close $fid
}

# ファイルから文字列を読み込む
proc ReadString {} {
    set fid [open str.txt r]
    set str [gets $fid]
    close $fid
    return $str
}

# main

WriteString "Hello! Hello!"
puts [ReadString]

[実行例]

$ ./rw.tcl
Hello! Hello!

$ cat str.txt
Hello! Hello!

上記サンプルは、以下の処理をしています。

  1. str.txt を作成
  2. 文字列を str.txt へ書き込み。
  3. str.txt の読み込み。
  4. 読み込んだ文字列を画面に出力。

catコマンドで確認するとstr.txtにHello! Hello!が書き込まれていることがわかります。※Windowsの場合はtypeコマンド

さらに詳しく説明すると、

ファイルのアクセスは、以下の3つの手順で行います。

  1. ファイルを開く(openコマンド)
  2. 読み書きする(getsコマンド、putsコマンド)
  3. ファイルを閉じる(closeコマンド)

[ファイル入出力の手順]

3つの手順について次の項目で1つ1つ説明します。

ファイルを開く - openコマンド –

ファイルの読み書きをするには、まず、プログラムとファイルを結びつける必要があります。この操作をファイルオープンと言います。

文字列の入力と出力について」の記事でチャネルとは、「データを受渡するための通路のことです。」と説明しましたが、ファイルオープンは、プログラムとファイルの間に、この通路を開いてファイルにアクセスができるようにします。

set fid [open str.txt w ]

この処理は、openコマンドで”str.txt”を作成して書き込み専用で開きます。openコマンドはファイルオープンするとチャネル識別子を返します。

チャネル識別子はプログラムから”str.txt”にアクセスするための通路の名前や番号のようなものです。

読み書きする(getsコマンド、putsコマンド)

ファイルにデータを書き込んだり、ファイルのデータを読み込むには、ファイルオープンした時に付与されたチャネル識別子を使ってファイルにアクセスします。

puts $fid "Hello!"

これは、チャネル識別子を使って str.txt にHello! を書き込みしています。

set str [gets $fid]

これは、チャネル識別子を使って str.txt の内容を変数strに読み込んでいます。

ファイルを閉じる(closeコマンド)

読み書きを終了すると、開いたチャネルを閉じる操作が必要です。

close $fid

次の項目でopenコマンドの詳細を説明します。

openコマンド

openコマンドの書式は以下のようになっています。

[書式]

open fileName
open fileName access
open fileName access permissions

このコマンドは、fileNameで指定したファイル、シリアルポート、またはコマンドパイプラインを開き、チャネル識別子を返します。

accessは、ファイル(またはコマンドパイプライン)にアクセスする方法を示します。以下の指定が可能です

rファイルを読み取り専用で開く。ファイルはすでに存在していなければならない。accessが指定されない場合、これがデフォルト値。
r+ファイルを読み書き両用で開く。ファイルはすでに存在していなければならない。
wファイルを書き込み専用で開く。既存のファイルを指定した場合、中身を空にする。存在しないファイルを指定した場合は、新しいファイルを作成する。
w+ファイルを読み書き両用で開く。既存のファイルを指定した場合、中身を空にする。存在しないファイルを指定した場合は、新しいファイルを作成する。
aファイルを書き込み専用で開く。存在しないファイルを指定した場合は、新しいファイルを作成する。書き込み位置はファイルの末尾に設定される。
a+ファイルを読み書き両用で開く。存在しないファイルを指定した場合は、新しいファイルを作成する。書き込み位置はファイルの末尾に設定される。

accessには、POSIX標準のフラグを指定することができます。フラグの1つにはRDONLYWRONLYまたはRDWRのいずれかでなければなりません。

RDONLYファイルを読み取り専用で開く。
WRONLYファイルを書き込み専用で開く。
RDWRファイルを読み書き両用で開く。
APPEND書き込み位置をファイルの末尾に設定する。
BINARY開いたチャネルを、fconfigure -translation binary に設定します。
CREAT存在しないファイルを指定した場合は、新しいファイルを作成する。(このフラグを指定せずに、存在しないファイルを指定した場合はエラーになります。)
EXCLCREATも指定されている場合、ファイルがすでに存在する場合はエラーが返されます。(ファイルが存在しない時だけ新しいファイルを作成する場合に利用する。)
NOCTTYファイルが端末デバイスである場合、このフラグはファイルがプロセスの制御端末になるのを防ぎます。
NONBLOCKファイルを開いている間にプロセスがブロックされないようにします。後続のI/O操作でプロセスがブロックされるのを防ぎます。 このフラグの正確な動作は、システムおよびデバイスに依存します。
その使用は推奨されません(ファイルを非ブロックモードにするには、fconfigureコマンドを使用することをお勧めします)。 詳細は、お使いのシステムの、openシステムコールのO_NONBLOCKフラグに関するドキュメントを参照してください。
参考:O_NONBLOCK
TRUNC既存のファイルを指定した場合、中身を空にする。

このフラグを複数指定するには「{ }」で囲みます。

例.
読み書き両用で開き、ファイルが存在しない場合は作成する。(既存のファイルは空にしない)

set fid [open /tmp/a.txt {RDWR CREAT}

permissionsは、新しく作成したファイルの使用許可を設定する場合に使います。
パーミッションのデフォルトは0666です。

パーミッションはUNIXのファイルのアクセス許可モードのことです。chmodコマンドの8進数での指定と同じです。

例.

 0666 : rw-rw-rw- 誰でも読み書き可能。
 0644 : rw-r--r-- 自分(オーナー)以外は読み取りのみ可能。
 0600 : rw------- 自分(オーナー)のみ読み書き可能。

[参考]
chmod

既存のファイルに追加で書き込みする

[サンプル] rw2.tcl 既存ファイルに書き込み

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"

# 既存ファイルに追加で書き込みする
proc WriteString {str} {
    set fid [open str.txt a ]
    puts $fid "$str"
    close $fid
}

# main

WriteString "Good morning!"
WriteString "Bye bye!"
WriteString "Have a nice day!"

WriteString {こんにちわ。
おはようございます。
バイバイ。
よい1日を。}

[実行例]

$ ./rw2.tcl

$ cat str.txt
Hello! Hello!
Good morning!
Bye bye!
Have a nice day!
こんにちわ
おはようございます。
バイバイ
よい1日を!

「Hello! Hello!」と書き込まれた str.txt に追加で書き込みする。

最初の3つは1行ずつ書込み。4つ目は、一度に複数行の書き込みしています。

作成したstr.txtは次回以降でも利用します。

次回は複数行あるファイルの読み込み方法について紹介します。

コメント

タイトルとURLをコピーしました