4

我们正在从当前的构建系统(一团糟)转移到使用 Ant 和 Ivy 的构建系统。我正在清理所有构建文件,并找到 jar 依赖项。我认为如果我可以稍微自动化它可能会更容易,通过检查签入项目的 jar,找到它们包含的类,然后将这些类与importJava 代码中的各种语句匹配。

我以前用过Archive::Tar,但Archive::Zip不是标准的 Perl 模块。(我担心有人会尝试我的脚本,在半夜打电话给我,告诉我它不起作用。)

我注意到IO::Uncompress::AnyUncompress is a standard module, so I thought I could try IO::Uncompress::AnyUncompress or at leastIO::Uncompress::Unzip` 也是一个标准模块。

不幸的是,这些模块的文档没有给出示例(根据文档,示例是待办事项)。

我能够成功打开我的 jar 并创建一个对象:

 my $zip_obj = IO::Uncompress::AnyUncompress->new ( $zip_file );

现在,我想看看内容。根据文档:

获取标头信息

用法是

$hdr  = $z->getHeaderInfo();
@hdrs = $z->getHeaderInfo();

此方法返回包含有关压缩数据流中每个标头字段的信息的散列引用(在标量上下文中)或列表或散列引用(在数组上下文中)。

好的,这不是一个对象Archive::TarArchive::Zip返回,也没有提到解析数据的方法或子例程。我将使用Data::Dumper并查看参考中包含哪些哈希键。

这是一个简单的测试程序:

#! /usr/bin/env perl
use 5.12.0;
use warnings;

use IO::Uncompress::AnyUncompress;
use Data::Dumper;

my $obj = IO::Uncompress::AnyUncompress->new("testng.jar")

    or die qq(You're an utter failure);

say qq(Dump of \$obj = ) . Dumper $obj;

my @header2 = $obj->getHeaderInfo;
say qq(Dump of \$header = ) . Dumper $headers->[0];

这是我的结果:

Dump of $obj = $VAR1 = bless( \*Symbol::GEN0, 'IO::Uncompress::Unzip' );

Dump of $header = $VAR1 = {
          'UncompressedLength' => 0,
          'Zip64' => 0,
          'MethodName' => 'Stored',
          'Stream' => 0,
          'Time' => 1181224440,
          'MethodID' => 0,
          'CRC32' => 0,
          'HeaderLength' => 43,
          'ExtraFieldRaw' => '¦-  ',
          'ExtraField' => [
                            [
                              '¦-',
                              ''
                            ]
                          ],
          'FingerprintLength' => 4,
          'Type' => 'zip',
          'TrailerLength' => 0,
          'CompressedLength' => 0,
          'Name' => 'META-INF/',
          'Header' => 'PK
     +N¦6                 META-INF/¦-  '
        };

其中一些看起来很有用。但是,我的所有条目都返回 `'Name' => 'META-INF/``,所以它看起来不像文件名。

是否可以使用IO::Uncompress::AnyUncompress(或什IO::Uncompress:Unzip至)通读存档并查看其内容中有哪些文件。而且,如果是这样,我该如何解析该标头?

否则,我将不得不Archive::Zip让人们知道他们必须从 CPAN 下载并安装它到他们的系统上。

4

1 回答 1

4

存档中的文件被压缩在不同的数据流中,因此您需要遍历流以获取各个文件。

use strict;
use warnings;
use IO::Uncompress::Unzip qw(unzip $UnzipError);

my $zipfile = 'zipfile.zip';
my $u = new IO::Uncompress::Unzip $zipfile
    or die "Cannot open $zipfile: $UnzipError";

die "Zipfile has no members"
    if ! defined $u->getHeaderInfo;

for (my $status = 1; $status > 0; $status = $u->nextStream) {
    my $name = $u->getHeaderInfo->{Name};
    warn "Processing member $name\n" ;

    if ($name =~ /\/$/) {
        mkdir $name;
    }
    else {
        unzip $zipfile => $name, Name => $name
            or die "unzip failed: $UnzipError\n";
    }
}
于 2013-04-30T01:00:16.320 回答