ファイル操作

 これも定番!CGIにはなくてはならない「ファイル操作」です。C/C++やVB、JAVAなど言語によってちょっとずつ操作方法が異なっていますので、ご注意下さい。

ファイルを開く

 ファイル操作において、ファイルからデータを読み出すと言うのは、非常に基本的で重要な作業です。Perlでは、ファイルを開くにはopen関数を使います。書式は以下のようになります。

open ファイルハンドル名, "ファイル名";

 open関数は、フアイルを開くのに成功すると真を、失敗すると偽を返します。「ファイルハンドル名」とは、スクリプト内でファイルを示す文字列で、通常Perlの予約語とぶつからないよう、全て大文字で表されます。又、ファイルハンドルには、識別の為の記号($や@など)は必要ありません。

 ファイルを開く際には、目的によってファイル名、又はファイルハンドルの先頭に以下のような記号を付けます。

目的

記述

読み取り "ファイル名" 又は"<ファイル名"
書き込み ">ファイル名"
追加 ">>ファイル名"
読み書き両用 "+<ファイル名"
読み書き両用(ファイル作成) "+>ファイル名"
読み書き両用(ファイルのオープン又は作成) "+>>ファイル名"
パイプに出力 "|UNIXのコマンド"
パイプから入力 "UNIXのコマンド|"

(1)読み取り

 ファイルからデータを読み取る時は、open関数でファイル名の前に「<」を付けるか、何も付けずに用います。この場合、ファイルの属性をユーザーが読み取りできるように設定しておかないといけません。ファイルが存在しない時もエラーになります。

 通常は、ファイルが存在しない場合や、何らかの原因で開けない時の為にエラー処理を記述します。Perlでは、このエラー処理の為にdie関数を用意しています。

(2)書き込み

 ファイルにデータを書き込む時は、open関数でファイル名の前に「>」を付けて用います。この場合、ファイルの属性をユーザーが書き込みできるように設定しておかないといけません。書き込みの場合には、既存のファイルがあり、中にデータがあったとしても、ファイルの先頭から上書きしながらデータを書き込んで行きます。ご注意下さい。又、ファイルが存在しない場合には、自動的に生成されます。

(3)読み書き両用

 ファイルからデータの読み取りとデータの書き込みを行いたい時は、open関数でファイル名の前に「+>」を付けて用います。この場合、ファイルの属性をユーザーが読み込み・書き込みができるように設定しておかないといけません。ファイルが存在しない場合には、自動的に生成されます。

(4)追加

 ファイルに対してデータを追加したい時は、open関数でファイル名の前に「>>」を付けて用います。この場合、ファイルの属性をユーザーが書き込みできるように設定しておかないといけません。追加の場合には、既存のファイルがあり、中にデータがあった場合、その最終行の後ろからデータを書き込んで行きます。ファイルが存在しない場合には、自動的に生成されます。

ファイルを閉じる

 一旦開かれたファイルは必ず閉じなくてはいけません。入出力の処理が終了し、ファイルハンドルが不要となったら、close関数を使ってファイルを閉じます。書式は以下のようになります。

close ファイルハンドル名;

 Perlでは他の言語と異なり、このように明示的にファイルを閉じなくても、ファイルハンドルを再オープンする時やスクリプトが終了した時には、そのファイルハンドルは自動的に閉じられます。しかし、やはり要らぬトラブルを避ける為にも、明示的にファイルを閉じるべきでしょう。

ファイルの入出力

 ファイルを開いただけでは目的の処理を行う事は出来ません。スクリプト内ではファイルの操作は「<ファイルハンドル>」と言う形で使います。これは、ファイルハンドルに結び付けられたファイルから1行ずつデータを読み出し、読み込んだ行を返します。実際の記述例は以下の通りです。

open INPUT, "<log.txt";  
while ($_ = <INPUT>) { ここは「while (<INPUT>) {」でも同じ。
   chop; chop関数・・・文字列の最後の文字を取り除きます。
   print "$_\n";
}  
close INPUT;  

 2行目の<INPUT>で、ファイルから1行ずつデータを読み出し、これをwhile文のループで繰り返し処理を行い、ファイルの内容を出力しています。読み出しがファイルの最終行に達すると、while文の条件式が偽となるので、ループを抜けます。

 この方法でファイルから入力を受け取ると、行末の改行コードまで受け取ってしまうので、3行目のchop関数でその改行コードを取り除いています。

 ファイルからの読み取りには、これ以外にもread関数があります。書式は以下のようになります。

read ファイルハンドル名, スカラー変数, 読み込む長さ

 これにより、ファイルハンドルからスカラー変数へ指定した長さの文字列が読み込まれ、格納されます。ここで指定する文字列の長さの単位はバイトです。read関数は、読み取りが成功すると読み込んだバイト数を、失敗すると未定義値(undef)を返します。実際の記述例は以下の通りです。

open INPUT, "<log.txt";  
$log_bytes = read INPUT, $chars, 256;  
print "読み込んだバイト数は$log_bytesです。\n"; ←256が返される。
print "読み込んだ文字列は$charsです。\n"; ←格納された文字列が返される。
exit;

 read関数は、CGIでPOST方式によるデータ送信を選んだ場合によく使われます。POST方式の場合、標準入力(<STDIN>)から環境変数「CONTENT_LENGTH」に収められたバイト分だけを読み取らなくてはいけないからです。

 次に、Perlでファイルに書き出す場合は、主にprint関数を使います。書式は以下の通りです。

print ファイルハンドル名 "出力";

 ここでファイルハンドルを指定しないと、画面への出力(標準出力)がデフォルトとなります。CGIスクリプトからWebブラウザへの出力も標準出力の為、ファイルハンドル名は必要ありません。このことは実際のスクリプト内容を見れば一目瞭然でしょう。

 ファイルの出力には、print関数以外にも、フォーマット付きで文字列を出力するprintf関数もあります。

ファイルを作る

 Perlにはファイルを作る為の関数は特にありません。しかし、これまでの説明にあるように、ファイルを開く際のモードを「書き込み」、「読み書き」、「追加」にして行えばファイルを作る事が出来ます。まとめると、以下のようになります。

open ファイルハンドル名, ">ファイル名";
open ファイルハンドル名, "+>ファイル名";
open ファイルハンドル名, ">>ファイル名";

ファイルの削除

 ファイルの削除にはunlink関数を用います。書式は以下の通りです。

unlink ファイル名;

 実際の使用例は以下の通りです。

unlink "test.txt";  
unlink test.txt, test2.txt; 複数削除する場合は、列挙する。

 あるディレクトリの全ファイル、またはその一部を削除したい場合には、ファイル名グロブ演算子<>」を用います。もし、カレントディレクトリの全ファイルを削除したい場合には、以下のように記述します。

unlink <*>;

 又、次のようにすれば、拡張子「*.txt」をもったファイルだけを削除出来ます。

unlink <*.txt>;

ファイル名の変更

 ファイル名を変更するには、rename関数を用います。書式は以下のようになります。

rename ("古いファイル名", "新しいファイル名");

 実際の使用例は以下のようになります。

rename ("log.txt", "log.bak");

ファイルのロック

 実際のCGIの運営においては、複数人のユーザーがファイルに同時にアクセスして、同時に保存してしまう場合が考えられます。このような場合、ファイルの中身が正常に処理されない危険性があります。(特にカウンターファイルなど)そこで、こう言った現象を防ぐ為にファイルロックと言う概念があります。ファイルロックとは、誰かがファイルを操作している間は、そのファイルにアクセスさせないと言うものです。これでファイルの同時保存の問題が解決出来ます。

 ファイルロックを行うにはflock関数を使います。書式は以下のようになります。

flock ファイルハンドル, 操作モード

 操作モードとは、flock関数の操作を定義するものです。通常、以下のようなモードがあります。

操作モード

意味

1 共有ロック(読み込みを許す)
2 排他ロック(読み書き禁止)
4 ロック中非ブロック(ロックされていたら帰る)
8 ロック解除

 通常用いるのは「排他ロック」が多いでしょう。これは、ロックがかけられていれば、解除されるまで待つと言うものです。

サブルーチン 前へ

HOME

次へ SSIについて