I just added an Intermediate Windows Skills course to our curriculum at the library, and one of the topics covered is software installation, and so something to extract ZIP files is needed, so that the participants can have practice installing software that comes packaged in a ZIP file. As I was checking the computers we use for the courses to make sure they're ready, I noticed one Win98 machine didn't have a simple ZIP file extractor. (It did have something, but it wasn't something I wanted to explain the use of within the course.) I tried installing PKWare's Reader, but it complained about a misssing DLL. I didn't feel like messing with it, and I remembered that I already had Archive::Zip installed on there (because it's used by the word search maker for creating an OpenOffice document), and so I just associated ZIP files with this simple Perl script:

#!/usr/bin/perl use Archive::Zip; for (@ARGV) { print "Unzipping: $_\n" if $debug; my $zip = Archive::Zip->new($_) or die "Unable to open $_: $!"; for my $m ($zip->members()) { print " Member: ".Dumper($m)."\n" if $debug; # $m is an object of class Archive::Zip::ZipFileMember print " ".$m->fileName()."$/"; $zip->extractMember($m); } }

This doesn't have a lot of features, but it does what we need for this course (double-click a ZIP file in Windows Explorer, and its contents are spilled out on the spot), and writing and installing it was faster than trying to solve the problem with the PKWare Reader.


$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/

Replies are listed 'Best First'.
Re: Simple ZIP extractor
by b10m (Vicar) on Dec 22, 2003 at 21:24 UTC

    Nice piece of simple code, but I'd like to add just a few lines to make the error handling a little nicer if the file in @ARGV doesn't exist ;)

    Right now, if I use a non existant file I get a lot of irrelevant (for the user) data:

    $ ./unzipper nonexistant.zip IO error: opening nonexistant.zip for read : No such file or directory + Archive::Zip::Archive::read('Archive::Zip::Archive=HASH(0x8120 +258)','nonexistant.zip') called at /usr/local/lib/perl5/site_perl/5.8 +.0/Archive/Zip.pm line 522 Archive::Zip::Archive::new('Archive::Zip::Archive','nonexistan +t.zip') called at /usr/local/lib/perl5/site_perl/5.8.0/Archive/Zip.pm + line 211 Archive::Zip::new('Archive::Zip','nonexistant.zip') called at +./unzipper line 6 Unable to open nonexistant.zip: at ./unzipper line 6.

    This can be solved by just a few extra lines:

    #!/usr/bin/perl -w use Archive::Zip; for (@ARGV) { if(! -r $_) { print "$_: $!\n"; exit 1; } print "Unzipping: $_\n" if $debug; my $zip = Archive::Zip->new($_) or die "Unable to open $_: $!"; for my $m ($zip->members()) { print " Member: ".Dumper($m)."\n" if $debug; # $m is an object of class Archive::Zip::ZipFileMember print " ".$m->fileName()."$/"; $zip->extractMember($m); } }

    Now the error will be slightly more helpful to l-users

    $ ./unzipper nonexistant.zip nonexistant.zip: No such file or directory
    --
    b10m
      Right now, if I use a non existant file I get a lot of irrelevant (for the user) data:

      Yes, quite so. My script wasn't intended to be used at the command-line, but to be associated with the ZIP filetype in Windows Explorer, for double-click unzipping. A real command-line zipfile utility would need some additional functionality.


      $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
Re: Simple ZIP extractor
by nimdokk (Vicar) on Dec 23, 2003 at 18:32 UTC
    Thats kind of nifty. I've been looking at doing something similar to put into our custom module that I've written. For that though, I'll need a few other options, such as path (or lack thereof) and so forth. Though I wish I could completely eliminate the need to have PKZIP on the system, we still need it to extract password protected files.


    "Ex libris un peut de tout"
      I have a script that pulls a password-protected Zip file from a partner's server, extracts the contents, uploads the contents to a servlet and then process the contents to pull related image files from an image server (one of the columns in the zipped file contains an image URL) and, depending on various things, may send the image to another servlet as well.

      For the life of me I couldn't find an abstracted password-processing module so I used a qx// function to invoke RedHat's unzip. Works fine but I'd rather have a different alternative.

Re: Simple ZIP extractor
by b10m (Vicar) on Feb 20, 2004 at 11:17 UTC

    Mmmm, I never thought I'd comment on this node again, but yesterday I tried to unzip a 2GB zip file with "unzip", the Linux app. That one died on me time after time for unknown reasons (one error was something like "write error. Disk full?" when I had plenty of disk space available).

    I gave this little snippet a try and -yes, unzipping a 2GB zip file takes a while, and I don't like .zip anyways, but that's besides the point- no errors, the snippet unzipped the .zip nicely :) Woohoo! Perl rocks.

    --
    b10m

    All code is usually tested, but rarely trusted.