2011-02-01 93 views
8

在這種情況下是否習慣於僅打開一次文件?我應該打開一個文件還是經常打開和關閉?

#!/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,然後運行一個Perl腳本,除了每次打開/關閉10000個不同的文件名100次之外什麼也不做。

請注意(關於場景#3 /#4),如果您非常關心不丟失任何數據,您不應該首先使用文件IO - 使用具有交付保證的數據庫或消息傳遞系統。

+0

另外,你要多少開銷與所有的開啓和關閉遭遇 - 他們沒有成本的操作。 – 2011-02-01 20:19:05

4

這是慣例,對於正常程序,打開每個文件,並保持打開的文件句柄,只要你的處理仍然有它的用途。

如果文件處理僅限於代碼的特定部分(例如初始化和關閉)或特定和相對罕見的事件(與重新讀取配置有關的信號處理程序或更新統計信息或調試轉儲)。

在這個例子中,你正在展示了額外的打開和關閉操作是完全多餘的(而且可能是昂貴的性能和系統開銷方面)。