windows - 使用存档获取“格式错误:找不到 EOCD 签名”
问题描述
下面的代码工作正常,除了一些 zip 文件我收到错误
格式错误:找不到 EOCD 签名 在 C:/LegacyApp/perl/lib/Archive/Zip/Archive.pm 第 695 行 Archive::Zip::Archive::_findEndOfCentralDirectory('Archive::Zip::Archive=HASH(0x375a730)', 'IO::File=GLOB(0x380eb90)') 在 C:/LegacyApp/perl/lib/Archive 调用/Zip/Archive.pm 第 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 文件有什么问题。
提前致谢
解决方案
似乎其中一些文件确实存在格式错误。然后您可以捕获这些故障并处理坏文件(记录名称或删除文件等),否则可以正常进行。
如果您显示的“错误”是异常(程序死亡),那么您可以捕获并处理它
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 ...
}
# control returns here, unless the block above does exit/die/croak/goto
在 Perl(模具)中处理异常的一种内置方法是通过eval的块形式。†</sup> 另请参阅$@
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__}
。然后,如果警告的消息与该正则表达式匹配,则将 adie
与该消息一起抛出。由于这是在内部触发的,eval
因此会像前面的代码示例一样对其进行处理。见%SIG
perlvar。
另一种方法是简单地为任何警告引发异常$SIG{__WARN__}
(仅在此块内!),然后处理eval
's 处理程序中的所有细节。
请注意,本地在所有这些中都很重要,因此我们不会更改警告在所有代码中的工作方式,而只是在此块中。
这应该可以正常工作,但请研究链接的文档。
†</sup> 曾经有$@
直接处理的微妙陷阱(在 v5.14 之前)。虽然这已经解决了,但所有这些确实是低级的,考虑使用模块可能是个好主意。这将包裹eval
+$@
以便于消化,并且可能更容易正确使用。
推荐阅读
- javascript - 我的节点应用程序中的 NPM 模块是否共享依赖项?
- pandas - Pandas:选择多行或默认使用新 API
- python - 用pyqt5关闭窗口时如何关闭串口
- r - add_column 适用于矩阵
- c# - 方法忽略类范围变量值更改
- drake - 德雷克的激光雷达
- select - 编译简单解码器时类型错误解析中缀表达式
- filter - Lucene 标记化/过滤器未按预期工作 | Solr分析混乱
- javascript - select2 在 webpack encore symfony 中不起作用
- spring-boot - Spring Boot Test 无法使用 JUnit 5 为自定义集成测试源集加载应用程序上下文