0

我有一个 perl 脚本,我从批处理或有时从命令提示符提供输入(文本文件)。当我从批处理文件提供输入时,有时该文件可能不存在。我想捕获 No such file exists 错误并在引发此错误时执行其他任务。请找到以下示例代码。

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.
4

2 回答 2

3

@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 大小的检查,因为如果您提供一个全部不存在的列表文件,它将在标准输入上等待(使用 <> 的另一面)。这假设您不想这样做。

但是,如果您不想从标准输入中读取,<>则可能是一个糟糕的选择;您不妨逐步浏览@ARGV. 如果您确实想要从标准输入读取的选项,那么您需要知道您处于哪种模式:

$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(<>) {
  #...
}
于 2012-11-15T13:49:52.770 回答
0

钻石算子<>意思是:

查看其中的名称@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 函数返回一个假值。所以总是open像这样调用

open my $filehandle "<", $filename or die "Can't open $filename: $!";

包含失败的$!原因。除了dieing,我们还可以做一些其他的错误恢复:

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
    }
}
于 2012-11-15T13:33:33.050 回答