下面的代码工作正常,除了一些zip文件我遇到错误
format error: can't find EOCD signature at C:/LegacyApp/perl/lib/Archive/Zip/Archive.pm line 695 Archive::Zip::Archive::_findEndOfCentralDirectory('Archive::Zip::Archive=HASH(0x375a730)', 'IO::File=GLOB(0x380eb90)') called at C:/LegacyApp/perl/lib/Archive/Zip/Archive.pm line 581 Archive::Zip::Archive::readFromFileHandle('Archive::Zip::Archive=HASH(0x375a730)', 'IO::File=GLOB(0x380eb90)',
使用下面的代码:
use Archive::Zip;
unzip($zipfile,$folder,$out);
sub unzip {
my ($archive, $want, $dir) = @_;
my $zip = Archive::Zip->new($archive);
foreach my $file ($zip->members) {
if (($file->fileName =~ /VERSION\/(.*?).cosipa.xlsx$/i)) {
$zip->extractMember($file,$dir.$file->fileName);
}
if ($file->fileName =~ /VERSION\/(.*?).txt$/i) {
$zip->extractMember($file,$dir.$file->fileName);
}
}
return 1;
}
如果我删除该特定的zip文件,则可以正常工作。但是,我需要一个能够同时处理这些zip文件的解决方案,如果可能的话,请让我知道代码和zip文件中的错误。
预先感谢
答案 0 :(得分:1)
似乎其中一些文件确实存在格式错误。然后,您可以捕获这些故障并处理错误的文件(记录名称或删除文件等),否则可以正常进行。
如果显示的“错误”是一个异常(程序死了),那么您可以捕获并处理该错误
eval { unzip($zipfile, $folder, $out) };
if ($@) {
say "Error: $@";
# Interrogate. (Is it the expected error or some other?)
# handle it: record the filename for later/delete it/etc ...
}
在Perl中处理{exception(仅die)“异常”的一种内置方法是通过eval的(块形式)。 †另请参见the $@
error variable in perlvar。
如果您的消息仅是警告,并且程序继续运行,则eval
将无法捕获该消息。一种检测到这种情况的方法是安装一个SIG{__WARN__}
钩子并在其中抛出一个die
,然后使用与上面相同的eval
# Block, so the change to how warnings work is scoped as tight as possible
HANDLE_ZIP: {
local $SIG{__WARN__} = sub {
die $_[0] if $_[0] =~ /^\s*format error:/; # raise exception, or
warn $_[0]; # re-emit the warning
};
eval { unzip($zipfile, $folder, $out) };
if ($@) {
# same as above...
}
};
现在,如果从unzip
中发出警告,而不是打印警告,则会调用具有分配给$SIG{__WARN__}
的引用的子对象。然后,如果警告消息与该正则表达式匹配,则将引发die
,并带有该消息。由于这是在eval
内部发生的,因此如上所述。参见%SIG
in perlvar。
另一种方法是简单地在$SIG{__WARN__}
中针对任何警告引发异常(仅在此块内!),然后在eval
的处理程序中处理所有详细信息。请注意,local在这里至关重要,因此我们不会更改警告在所有代码中的工作方式。
这是一个草图(即使它可以按原样工作)。请研究链接的文档。
†曾经有一些微妙的陷阱,可以直接处理$@
(v5.14之前)。虽然已经解决了所有问题,但所有这些的确是低级的,考虑使用模块代替可能是一个好主意。这样可以包装eval
+ $@
以便于消化,也可能有助于正确使用。
请寻找替代方案,但请记住,时尚一直在变化,并且许多年来已经出现和消失了。这是最近的discussion中的一些选项。