ファイルハンドラの扱い
オープン
ファイルのオープンにはopenを使う。
open(HANDLE,filename)
open(HANDLE)
open HANDLE
基本の型は一番上。ファイル名を指定しつつ、そのハンドラをHANDLEで指定する。
filenameを指定しなかった場合、HANDLEのスカラー値がファイル名として使われる。
ファイルを開くときに失敗する可能性があるので、例外対応するのがふつう。
open(HANDLE, "./file.txt") || die "Can't open: $!\n";
$!にはエラーMsgが入る。
open の後には;はいらないみたい。
出力内容ファイルに書き込む時のオープンはこんな感じ。
open(HANDLE, "> $file") || die "Can't open: $!\n";
print HANDLE "test\n";
このtestは$file のファイルに出力される。printのところにHANDLE設定してるからね。
これ設定しないと、デフォルト(STDOUT)のまま。
open 時に > を入れてるところがポイント。closeすれば、この状態から解き放たれる。
追記したい場合は、>> にする。
|も使える。これをするとつまり、ハンドラに与えられたものを echo して、パイプ後の処理をするイメージ。
open(HANDLE, "| wc -l") || die "Can't open: $!\n";
print HANDLE "one\ntwo\nthree\n";
これをすると3とでるよ。printの2引数が3行だからね。
コマンド| という形だったら、コマンドの実行結果がハンドラに渡される。
コマンド| の形は、コマンドの結果を1行1行処理したいときによく使うぽいぞ。
open (PROC, ps -aux | ) || die "Error: $!\n";
while ($line = <PROC>) {
print "$line" if $line =~ /^tomcat/;
}
select
selectで明示的にデフォルトファイルハンドラが指定できる。
またこの処理の返り値は、さっきまで設定されてたファイルハンドラ、だから戻しやすい。
open (FILEOUT, "> output.txt") || die "Can't open output.txt: $!\n";
print "1\n";
$oldhandle = select(FILEOUT);
print "2\n";
select ($oldhandle);
print "3\n";
1と3は標準出力される。
クローズ
ファイルのクローズにはcloseを使う。
close(HANDLE)
このとき、openでなんか処理を書いてても、必ずその処理が終了する。
ファイルロック
ファイルのロックには、flockが使える。他にもいろいろ方法はあるっぽいけど。
ロックの種類
| 1 |
読み込み中なので、書き込みをロック。 |
| 2 |
書き込み中なので、読み書き両方をロック。 |
| 4 |
使おうとしたら、とにかくエラー |
| 8 |
ロック解除 |
1と2は、自動的にアンロックされるまで待つ。
open (FILE, "> file") || die "Open Error: $!\n";
flock (FILE, 2) || die "File Lock Error: $!\n";
print FILE "test\n";
flock (FILE, 8);
fileに対して読み書きロックをかけといて、使ったあとはアンロックしてます。
ハンドラのコピー
open(SAVED, ">&STDOUT") || die "hoge";
STDOUTの前に&がついてるのがポイント。
今の時点で、STDOUTに流したときと同じことをするのが、SAVED。
この後でSTDOUTの中身が変わっても、SAVEDは変わらない。
seek, tellによるアクセス
seekを使うと、ファイルの好きなところに対してアクセスができます。
seek(HANDLE, OFFSET, POSITION)
POSITION は、以下から選ぶ。
- 0 ファイルの先頭
- 1 現在の位置(ハンドラは最後にアクセスされた位置を覚えてる)
- 2 ファイルの末尾
OFFSETはそこから何バイトさきから始めるか。負数でもOK。
open (FILEOUT, "names.txt") || die "Can't open names.txt: $!\n";
print "First loop\n";
while (<FILEOUT>) {
print;
}
print "-----\n";
seek(FILEOUT, 0, 0);
print "Second loop\n";
while (<FILEOUT>) {
print;
}
seekがあるおかげで2回のループができる。
これがないと、FILEOUTのポインタが一番最後になってるので普通にはループできない。
tellは最後に読み込んだファイルハンドラの現在の位置を返す。
ハンドラを指定することも可能。
eof
ファイルハンドラがファイルの終着点にいるかどうかを見る。
while(FILE) {
print if /^Start/ .. eof();
}
こうすればStartという行があったら、最後の行までprintが可能。
最終更新:2011年07月25日 23:42