2010-07-13 97 views
3

我想在下面的Perl程序中未打開文件時執行一些任務。但是當我運行它時,出現語法錯誤。它出什麼問題了?perl打開文件錯誤處理

my $LOGPATH = $ENV{DATA_OU}; 
my $LOGFILE = "cdj_rep" . "." . "test" . ".rpt"; 

if ! (open(OUT,">$LOGPATH/test1/work/$LOGFILE")) { 
    print "testin"; 
    return; 
} 

close(OUT); 

回答

9

該!需要去括號內:

if (! open (out, 
+0

非常感謝信息 – Arav 2010-07-13 01:26:14

11

我把它寫成

my $LOGPATH = $ENV{DATA_OU}; 
my $LOGFILE = "cdj_rep.test.rpt"; 
my $path = "$LOGPATH/test1/work/$LOGFILE"; 

open my $fh, ">", $path or do { 
    warn "$0: open $path: $!"; 
    return; 
}; 

close $fh or warn "$0: close $path: $!"; 

放置在$path整個路徑,這樣你就不必多次重複它,如果你需要要改變它,你可以在一個地方這樣做。

open的調用使用詞法文件句柄(my $fh)而不是裸句句柄。這是一個很好的開發習慣,因爲將$fh傳遞給subs或將其填充到數據結構中往往會更自然地進行語法分析。

它也使用open的3參數形式,因此您不必擔心特別解釋路徑中的字符。在你的代碼中,這可能看起來不是什麼大不了的事情,但這是開發另一個好習慣。

用於檢查的open是否成功常見的成語是

open my $fh, "<", $path 
    or die "$0: open $path: $!"; 

使用if (!open ...unless (open ...將被罰款,但有一個詞法文件句柄,你需要擔心的範圍的問題。您似乎正在使用該檢查作爲警衛,因此編寫open or ...時將文件句柄保留在範圍內以便成功執行。如果它失敗了,你需要執行兩條語句,所以你需要像上面那樣將它們包裝在do { ... }中。

還要注意傳遞給warn錯誤消息的內容:

  • 說有一個錯誤($0
  • 什麼設法做(open $path
  • 和爲什麼會失敗的程序($!

warndie運營商發送的OUTP ut到標準錯誤,這允許在別處重定向錯誤消息的靈活性。例如,如果發生I/O錯誤,可能會發生這種情況,例如,如果您爲創建的文件或附加文件創建句柄,則應檢查其是否失敗。

+2

Schwern說我們應該使用'autodie'。 – 2010-07-13 02:12:11

+1

+1:爲較新的,更好的Perl開放技術寫的很好的建議。 – dawg 2010-07-13 17:03:53

+0

感謝您拋光$ 0和$!內置變量。對於像我這樣的新手非常有用。 另外,使用大寫的FILE_HANDLES不是一個約定嗎? – 2013-11-15 15:45:56