我有一个perl脚本,我从批处理或有时从命令提示符提供输入(文本文件)。当我从批处理文件提供输入时,有时该文件可能不会存在。我想捕获"不存在此类文件"错误,并在引发此错误时执行其他任务。请找到下面的示例代码。
while(<>) //here it throws an error when file doesn't exists.
{
#parse the file.
}
#if error is thrown i want to handle that error and do some other task.
在使用<>
之前过滤@ARGV
:
@ARGV = grep {-e $_} @ARGV;
if(scalar(@ARGV)==0) die('no files');
# now carry on, if we've got here there is something to do with files that exist
while(<>) {
#...
}
<>
从@ARGV中列出的文件中读取,因此如果我们在它到达那里之前对其进行过滤,它不会尝试读取不存在的文件。我添加了对@ARGV大小的检查,因为如果您提供一个全部不存在的列表文件,它将等待 stdin(使用 <> 的另一面)。这假设您不想这样做。
但是,如果您不想从 stdin(标准)读取,<>
可能是一个糟糕的选择;您不妨逐步浏览 @ARGV
中的文件列表。如果您确实想要从 stdin 读取的选项,那么您需要知道您处于哪种模式:
$have_files = scalar(@ARGV);
@ARGV = grep {-e $_} @ARGV;
if($have_files && scalar(grep {defined $_} @ARGV)==0) die('no files');
# now carry on, if we've got here there is something to do;
# have files that exist or expecting stdin
while(<>) {
#...
}
菱形运算符<>
的意思是:
查看
@ARGV
中的名称,并将它们视为要打开的文件。 只需遍历所有这些,就好像它们是一个大文件一样。 实际上,Perl 使用 ARGV 文件句柄来实现此目的。如果未给出命令行参数,请改用
STDIN
。
因此,如果一个文件不存在,Perl 会给你一个错误消息 ( Can't open nonexistant_file: ...
),然后继续下一个文件。这是您通常想要的。如果不是这种情况,只需手动执行即可。从perlop
页面窃取:
unshift(@ARGV, '-') unless @ARGV;
FILE: while ($ARGV = shift) {
open(ARGV, $ARGV);
LINE: while (<ARGV>) {
... # code for each line
}
}
open
函数在遇到问题时返回 false 值。所以总是调用open
喜欢
open my $filehandle "<", $filename or die "Can't open $filename: $!";
$!
包含失败的原因。我们可以执行其他一些错误恢复,而不是die
use feature qw(say);
@ARGV or @ARGV = "-"; # the - symbolizes STDIN
FILE: while (my $filename = shift @ARGV) {
my $filehandle;
unless (open $filehandle, "<", $filename) {
say qq(Oh dear, I can't open "$filename". What do you wan't me to do?);
my $tries = 5;
do {
say qq(Type "q" to quit, or "n" for the next file);
my $response = <STDIN>;
exit if $response =~ /^q/i;
next FILE if $response =~ /^n/i;
say "I have no idea what that meant.";
} while --$tries;
say "I give up" and exit!!1;
}
LINE: while (my $line = <$filehandle>) {
# do something with $line
}
}