アットウィキロゴ

perl > fileh

ファイルハンドラの扱い

オープン

ファイルのオープンには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