Perl reading zip files using IO :: Uncompress :: AnyUncompress

We are moving from our current build system (which is a mess) to one that uses Ant with Ivy. I clean up all build files and detect jar dependencies. I thought it might be easier if I could automate it by going through the banks that are checked in the project, finding which classes they contain, then matching these classes with various import statements in Java code.

I used to use Archive::Tar , but Archive::Zip not a standard Perl module. (I'm worried that someone is going to try my script, call me in the middle of the night and say that it does not work.)

I noticed that IO::Uncompress::AnyUncompress is a standard module, so I thought I could try IO :: Uncompress :: AnyUncompress or at least IO :: Uncompress :: Unzip`, which is also a standard module.

Unfortunately, the documentation for these modules does not provide examples (according to the documentation, examples are todo).

I can successfully open my jar and create an object:

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

Now I want to see the contents. According to the documentation:

getHeaderInfo

Using

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

This method returns either a hash link (in a scalar context), or a list or hash links (in an array context) that contains information about each of the header fields in the compressed data stream (s).

Well, this is not an object like Archive::Tar or Archive::Zip , and there are no methods or routines mentioned for data analysis. I will use Data::Dumper and see what hash keys are in the link.

Here is a simple test program:

 #! /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]; 

And here are my results:

 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/¦- ' }; 

Some of them look useful. However, all my records return `` Name '=>' META-INF / ``, so it does not look like a file name.

Can I use IO::Uncompress::AnyUncompress (or even IO::Uncompress:Unzip ) to read the archive and see what files are in its contents. And, if so, how can I parse this header?

Otherwise, I will have to go with Archive::Zip , and let people know that they need to download and install it from CPAN on their systems.

+4
source share
1 answer

Files in the archive are compressed in different data streams, so you need to iterate over the streams to get individual files.

 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"; } } 
+3
source

All Articles