Perl读取压缩文件IO::Uncompress::AnyUncompress



我们正在从当前的构建系统(这是一个烂摊子)转移到一个使用Ant和Ivy的系统。我正在清理所有的构建文件,并找到jar依赖项。我认为如果我能自动化一点可能会更容易,通过遍历检入项目的jar,找到它们包含的类,然后将这些类与Java代码中的各种import语句进行匹配。

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

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

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

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

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

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

getHeaderInfo

使用

$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)来读取归档文件并查看其内容中有哪些文件?如果是,我如何解析那个header?

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

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

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 $namen" ;
    if ($name =~ //$/) {
        mkdir $name;
    }
    else {
        unzip $zipfile => $name, Name => $name
            or die "unzip failed: $UnzipErrorn";
    }
}

最新更新