2010-07-13 149 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