vegasjoe has asked for the wisdom of the Perl Monks concerning the following question:

Hello brothers, I am trying to extract *.gz in Perl. This program will run on Win32 servers running Perl 5.8. I tried to use Archive::Zip because it has a PPD file for Perl 5.8. However, this did not work. Archive::Zip could not read the *.gz file. BTW, I usually extract this file using Winzip or Winrar. It seems that Archive::Any does not have a PPD file for perl 5.8. Are there any other native Perl solutions not a system call wrapper solutions that I am not aware of?

Replies are listed 'Best First'.
Re: How to Unzip *.gz files (code)
by tye (Sage) on Dec 28, 2004 at 03:28 UTC

    The code I use and so have just lying about is:

    use strict; BEGIN { @ARGV= map { glob($_) } @ARGV } use Compress::Zlib; die "Usage: $0 {file.gz|outfile=infile} ...\n" unless @ARGV ; foreach my $infile (@ARGV) { my $outfile= $infile; if( $infile =~ /=/ ) { ( $outfile, $infile )= split /=/, $infile; } elsif( $outfile !~ s/[._]gz$//i ) { $infile .= ".gz"; } my $gz= gzopen( $infile, "rb" ) or die "Cannot open $infile: $gzerrno\n"; open( OUT, "> $outfile\0" ) or die "Can't write $outfile: $!\n"; binmode(OUT); my $buffer; print OUT $buffer while $gz->gzread($buffer) > 0; die "Error reading from $infile: $gzerrno\n" if $gzerrno != Z_STREAM_END; $gz->gzclose(); close(OUT) or warn "Error closing $outfile: $!\n"; }

    where the BEGIN line is there to compensate for stupid mistakes in the construction of Win32 back a decade or so that we are still paying for and the unusual usage is to allow me to unzip several files to non-default locations with a single command. Note that it doesn't delete the *.gz file after unzipping, since I usually find that I instead want to delete the uncompressed file after I've extracted what I needed from it (and I want to keep the compressed file around in case I need to extract more stuff later).

    - tye        

Re: How to Unzip *.gz files
by jonadab (Parson) on Dec 28, 2004 at 05:01 UTC
    I tried to use Archive::Zip because it has a PPD file for Perl 5.8

    The reason this won't work is because Archive::Zip is for working with ZIP files in PKWare format, the same as pkzip and pkunzip or info-zip. .gz is an entirely different, unrelated type of file. (Both filetypes involve compression, but for that matter so do .arj and .lzh, neither of which you can open with either Archive::Zip nor Compress::Zlib.)

    BTW, I usually extract this file using Winzip or Winrar

    The standard program to use for extracting these is gunzip, which comes with gzip. However, don't confuse this product with pkzip -- they both have the letters "z", "i", and "p" in their names, but they don't handle the same format. (The word "zip" is pretty heavily overloaded in computer software circles. Other apps that use this word include Mark Howell's Zip (which is a z-machine emulator; Frotz and WinFrotz are derived from it), jzip and XZip and MaxZip (other z-machine emulators derived from Zip), 7zip (another compression program that also has its own archive format that neither pkzip nor gzip can open), and ZipExpress (which has to do with postal codes). I think in the 80s there was some modem software for DOS that used the word "Zip" in its name, but I don't recall the precise details. Anyway, those are just the ones I could list off rather quickly; there are many more. Basically, the word "zip" doesn't necessarily imply compatibility with PKZip, and gzip in particular is not compatible with it but has a completely different format.) If WinZip handles both, that's because its creators have deliberately chosen to program support for both.

    As others have pointed out, the most common Perl module for working with gzip format is Compress::Zlib. If you can't find a PPM of that, you may be interested in Compress::Zlib::Perl, a pure-Perl implementation. (A pure Perl implementation can be installed simply by copying the .pm file into any directory listed in @INC, so you don't need to have CPAN.pm working to install it (although sooner or later you're probably going to want a working CPAN.pm for some other reason).)


    "In adjectives, with the addition of inflectional endings, a changeable long vowel (Qamets or Tsere) in an open, propretonic syllable will reduce to Vocal Shewa. This type of change occurs when the open, pretonic syllable of the masculine singular adjective becomes propretonic with the addition of inflectional endings."  — Pratico & Van Pelt, BBHG, p68
Re: How to Unzip *.gz files
by William G. Davis (Friar) on Dec 28, 2004 at 00:20 UTC
Re: How to Unzip *.gz files
by Zaxo (Archbishop) on Dec 28, 2004 at 06:32 UTC

    If your gzipped files are just compressed single files, and not tar archives, PerlIO::gzip can be handy (Perl 5.8).

    use PerlIO::gzip; { local $_; open my $ofh, '>:raw', $outpath or die $!; open my $ifh, '<:gzip', $inpath or die $!; print $ofh $_ while <$ifh>; close $ifh or die $!; close $ofh or die $!; }
    Has anybody written a tar layer? It would be (at the very least) non-trivial to find sane semantics. You wouldn't want to have diropen or glob semantics sticking its snout into open!

    After Compline,
    Zaxo