- ベストアンサー
Perlのtruncateについて
- + test.txt 0 1 2 3 + main.cgi open(FH, "<test.txt"); my @Log = <FH>; truncate(FH, 0); seek($FileHandle, 0, 0); print(FH "4"); close(FH); これで、main.cgiを実行すると、test.txtの中身は 4 1 2 3 となってしまいます。truncateがきいてないようなのですが、なぜでしょうか。 truncate(FH, 0) or die "error"; とすると、errorと表示されてしまいます。 なぜこうなるのでしょうか。 致命的エラーがでるわけでもないので、環境が悪いわけではないような気がするのですが。 flockをしたいのですが、他にファイルの中身を空にする方法とかありませんか。
- Perlのtruncateについて質問です。使用したコードは以下の通りです。 ```perl open(FH, "<test.txt"); my @Log = <FH>; truncate(FH, 0); seek($FileHandle, 0, 0); print(FH "4"); close(FH); ```
- 上記のコードを実行すると、test.txtの中身は以下のようになってしまいます。 ``` 4 1 2 3 ``` しかし、`truncate(FH, 0)`を実行してもエラーが発生せず、中身が空になりません。なぜこのような結果になるのでしょうか。また、`truncate(FH, 0) or die "error";`とすると、"error"と表示されます。なぜエラーが発生するのでしょうか。環境の問題ではないと考えていますが、なぜこのような現象が起きるのでしょうか。さらに、他にファイルの中身を空にする方法や、`flock`を使った方法があれば教えていただきたいです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
型グロブは良く覚えていないのですが、 > sub FileOpen { > local *FH = shift; と受けるなら、呼び出し側も > my @Log = FileOpen(FH, "test.txt"); このFHをグロブで渡さないといけないと思います。 FileOpen(*FH, ... ところで最近 (5.005以降?)であれば、ファイルハンドルに スカラー変数を使うことができます。 サブルーチンで値を操作させるにはリファレンスを渡さなければならない という制限はありますが、型グロブよりはいいんじゃないかと。 use strict; sub my_open1 { local *FH = shift; open FH, '>', shift or die $!; } sub my_open2 { my $fh_ref = shift; open $$fh_ref, '>', shift or die $!; } sub my_open3(\$$) { my $fh_ref = shift; open $$fh_ref, '>', shift or die $!; } my_open1(*F, "temp1.txt"); print F "hello, world\n"; close F or die $!; my $fh1; my_open2(\$fh1, "temp2.txt"); print $fh1 "hello, world\n"; close $fh1 or die $!; my $fh2; my_open3($fh2, "temp3.txt"); print $fh2 "hello, world\n"; close $fh2 or die $!; openだけ置き換えてますが、closeも同じようにできます。
その他の回答 (1)
- sakusaker7
- ベストアンサー率62% (800/1280)
> truncate(FH, 0) or die "error"; > とすると、errorと表示されてしまいます。 ここで truncate FH, 0 or die "error: $!"; のようにするとどんなメッセージが出てきますか? > flockをしたいのですが、他にファイルの中身を空にする方法とかありませんか。 ファイルのロックをしたいのなら、別のやり方もあるので ファイルを空にすることにこだわることはないと思いますが。 どっちが優先ですか?
補足
error: Bad file descriptore とでました。 というか、どうやらラッパー関数をつくっていたのがエラーの原因だったようです。 sub FileOpen { local *FH = shift; my $szFile = shift; my @Data; open(FH, "+<${szFile}"); flock(FH, 2); @Data = <FH>; seek(FH, 0, 0); return @Data; } sub FileClose { local (*FH) = @_; truncate(FH, 0) or print "Error > $!"; flock(FH, 8); close(FH) or print("e"); } my @Log = FileOpen(FH, "test.txt"); print(FH "4"); FileClose(FH); 実際はこんな風なラッパー関数を作りたいです。 ただ、これだと書き込みとクローズができてないみたいなのです。 どうすればよいのでしょうか。 質問が変わってしまいまして、申し訳ありません。。。
お礼
ありがとうございます! うーん。。。Perlはいろいろ難しいですね;;