如果打开文件失败,是否必须使用die?

时间:2013-06-25 20:02:50

标签: perl

大部分时间,我都这样做:

open FH, ">file.txt" or die "Cann't open file: $!";

是否必须使用die?如果我希望我的脚本继续(如果文件无法打开则忽略错误),我该怎么办?

9 个答案:

答案 0 :(得分:21)

您可能想要执行类似

的操作
if(open my $fh, ">", "file.txt") {
    # do stuff with file
    close $fh;
}
else {
    # do stuff without file
} 

答案 1 :(得分:8)

如果代码无法访问该文件,则代码不必die

如果写入文件是可选的,您可以这样做:

my $file_is_ok = 0;
open FH, ">file.txt" and $file_is_ok = 1;
warn "No logging available" unless $file_is_ok;

然后,无论您想要使用文件句柄,都可以先检查它是否正常:

$file_is_ok and print FH "Something happened";

通常你会想要比上面更多的抽象,但我希望这足以开始。

答案 2 :(得分:5)

不,绝对不必使用die,否则失败的open只会退出程序。这只是一个常用的构造,因为通常如果你不能打开文件就没有意义继续,但实际上没有要求die或做其他任何事情。

答案 3 :(得分:1)

我可能会这样做:

sub process_file {
    my $file = shift;
    open(my $fh, ">", $file) or return;
    # write to file ...
}

答案 4 :(得分:1)

open(my $fh, ">", $file) or print "open failed , you are on your own\n";

答案 5 :(得分:0)

建议您使用croak()中的Carp,尤其是模块或对象。见http://perldoc.perl.org/Carp.html

Carp是一个标准模块,与所有标准模块一样,安装了Perl。 perlmodlib中提供了所有标准模块的列表。见http://perldoc.perl.org/perlmodlib.html

答案 6 :(得分:0)

很抱歉回复了几个月的问题,但我这样做的方法是实现我自己的die样式子程序:

sub fail {
    my $text = $_[0];

    # Do error-related stuff here, like send an email
    die($text) # or just exit
}

open(my $fh, ">file.txt") or fail("Unable to open file: $!");

答案 7 :(得分:-1)

您可以使用try catch块,使用Try :: Tiny或类似的东西。

答案 8 :(得分:-1)

如果您尝试执行的操作是在打开文件时遇到错误而避免退出程序,则忽略die不是正确的方法。 die是Perl的异常机制;它默认中止程序的事实是偶然的,而不是基本的属性。如果提供异常处理程序,则保留控制权。正确的方法是捕获异常并在finally块中进行清理。

use 5.10.0;
use Try::Tiny;

my ($infile, $FH);
try {
    open $infile, '<', 'infile.txt' or die "Can't open infile";
    try { 
        open $FH, '>', 'file.txt'   or die "Can't open outfile";
        my $line = <$infile>;
        print $FH $line;
        say 'Cleaning up $FH';
        close $FH;
    } finally {
        say 'Cleaning up $infile';
        close $infile;
    } catch {
        die $_;
    };
} catch {
    die $_;
};

因此,如果open $infile ...失败,diecatch块,这会重写并中止脚本。但是,一旦我们打开$infile,如果open $FH失败,就死于一个也会中止该程序的catch块,但会强制close $infile先发生。文件句柄不是在程序退出之前清理资源的最佳示例,因为解释器会自动关闭文件,但基本的想法就在那里。

如果你不喜欢嵌套的try块,你可以通过检查哪个异常导致块中止并根据它确定需要清理来实现非常类似的效果。这有点脆弱,但比提及goto的任何内容都更强大。