2011-02-01 39 views
8

このような場合は、ファイルを1回だけ開くのが通例ですか?ファイルを開いたままにしておくか、頻繁に開閉する必要がありますか?

#!/usr/bin/env perl 
use warnings; 
use 5.012; 
use autodie; 

my $file = 'my_file'; 

open my $fh, '>>', $file; 
say $fh "Begin"; 
close $fh; 

$SIG{INT} = sub { 
    open my $fh, '>>', $file; 
    say $fh "End"; 
    close $fh; 
    exit 
}; 

my $result; 
while (1) { 
    $result++; 
    # ... 
    # ... 
    # ... 
    open my $fh, '>>', $file; 
    say $fh $result; 
    close $fh; 
    sleep 3; 
} 

答えて

20

短い答えは:ほとんどの場合、あなたは一度だけ /クローズを開く必要があります。以下に詳細を示します。

それを行うかどうかの決定は、4つの物事に依存します。

  1. は、ファイルに書き込む必要があるかもしれませんが、他のプロセスはありますか?

    この場合、ファイルをロックする必要があります。同時に使用するように設計されたプロセスの適切な動作は、ロックされた共有リソースをできるだけ早く解放して他のユーザーがロックを取得できるようにすることです。

  2. オープンする必要があるファイルがたくさんありますか?

    もしそうなら、開いているファイルが多すぎるファイルハンドルが不足している可能性があるため、終了する必要があります。

  3. プログラムがクラッシュした場合に、ファイル内のデータが失われる程度。

    バッファからファイルにデータを保存する必要がある場合は、それをフラッシュする必要があります。これは頻繁に閉じることで行うことができますが、より良い解決策は、頻繁なフラッシュまたはファイルハンドルの自動フラッシュをオンにすることです。

  4. ディスクスペースが足りなくなってもファイルを閉じることができない場合はどうですか?

    もしそうなら、ファイルを閉じる/再オープンする頻度が増えるほど、ファイルシステムがいっぱいになり、最後にopenが書き終わってから何を書いても失われるデータは少なくなります。

    他のシナリオでは

、唯一のオープン/ __DIE__ハンドラで(まあ、プラス多分余分近いとEND{}ブロック(および大部分の時間に一度近くに、あなたはおそらく他のシナリオになります)。

ファイルのオープンとクローズはシステムリソースを無駄にするだけでなく、コードを長くするので、ファイルのオープンとクローズは高価な操作であり、両方のシステムコール(ユーザランドからカーネルに強制的にジャンプする可能性があります) 、および余分なディスクIOは非常に高価なリソースです。それを確認するには、あなたのOでいくつかのシステム使用量測定ユーティリティを実行してくださいSを実行し、10000回の異なるファイル名を10000回開いたり閉じたりする以外は何もしないPerlスクリプトを実行します。

に注意してください(に関するシナリオ#3 /#4)あなたはどのようなデータを失っていないについて大いに気にしている場合、あなたが最初の場所でファイルIOを使用すべきではないこと - データベースまたは配達保証付きメッセージングシステムを使用します。

+0

また、すべての開閉に関して遭遇するオーバーヘッドはどれくらいありますか?コストのかからない操作です。 –

+0

私は自分のレスポンスに同時性とロックの考慮事項を含めることを考えましたが、彼の質問にはあまりにも絡み合っていると判断しました。しかし、彼はロック/フラッシングと開閉を組み合わせている可能性があります。ロックアウトを使用する必要があり、ロック競合やファイル/バッファの不一致のリスクを最小限にするために、書き込み操作後に明示的にフラッシュする必要があります。 –

+0

@ S.Lott - それは一般的な "無駄なシステムリソース"の見出しですが、少し拡大していきます:) – DVK

4

通常のプログラミングでは、各ファイルを開いて、処理がまだ使用されている限り、開いているファイルハンドルを保持することが慣例です。

ファイルの処理がコードの特定の部分(初期化やシャットダウンなど)に限定されている場合や、特定の比較的まれなイベント(設定を再読み込みしたり、デバッグダンプ)。

この例では、余分なオープン操作とクローズ操作が完全に余計に(パフォーマンスやシステムオーバーヘッドの点で高価になる可能性が高い)表示しています。

関連する問題