ファイルの保存
ここまでいくつかの見落としがちな処理を見てきましたが、
ファイルを確実に書き込むためには、
- (内容の差し替えだった場合に)
書き換え途中の状態にならないこと - ユーザに対して書き込み完了を返したあとは、
ディスクがクラッシュしない限り、 データが消えないこと
UNIX系OSでこれらの要件を満たすには、
# ①適当なテンポラリファイル名(格納先と同ディレクトリ)
my $newfn = "tmp.$$";
# ②ファイルを書いてfsync
open my $fh, '>', $newfn
or die "failed to open file:$newfn:$!";
print $fh $data;
IO::Handle::flush($fh);
or die "flush failed:$!";
IO::Handle::sync($fh);
or die "fsync failed:$!";
close $fh;
# ③古いファイルに別名を付与(必要ならば)
link $fn, "$fn~"
or die "failed to link $fn to $fn~:$!";
# ④新しいファイルに差し替え
rename $newfn, $fn
or "failed to rename $newfn to $fn:$!";
# ⑤ディレクトリエントリをfsync
sync_dir('.');
また、
sub sync_dir {
my $dir = shift;
sysopen my $d, $dir, O_RDONLY
or die "failed to open directory:$dir:$!";
open my $d2, '>&', fileno($d)
or die "dup(2) failed:$!";
IO::Handle::sync($d2)
or die "fsync(2) failed:$!";
}
これではあまりに複雑だということで、
まとめ
ファイルの保存は、
おわりに
以上、
OSを制御する知識はPerlでプログラムを書く場合以外にも、
次回の執筆者はacotieこと横山彰子さんで、