in reply to Re^2: Reading a .txt file under 2 levels of compression
in thread Reading a .txt file under 2 levels of compression

Well, from my understanding of the docs (of which I quoted parts in my previous post), this ought to extract the inner ZIP file from the outer ZIP file, into a string:
use IO::Uncompress::Unzip qw(unzip $UnzipError); my $file = '2.zip'; my $inner; unzip $file, \$inner, Name => '1.zip';
after which you can continue:
my $txt; unzip \$inner, \$txt, Name => '1.txt';
and now the text will be in the string $txt. (Caveat: untested)

Apparently the "Name => $name" part is optional if the ZIP archive contains only one file (what they call a "member file"):

Say you have a zip file, file1.zip, that only contains a single member, you can read it and write the uncompressed data to the file file1.txt like this.
unzip $input => $output or die "unzip failed: $UnzipError\n";

If you have a zip file that contains multiple members and want to read a specific member from the file, say "data1", use the Name option

unzip $input => $output, Name => "data1" or die "unzip failed: $UnzipError\n";

Replies are listed 'Best First'.
Re^4: Reading a .txt file under 2 levels of compression
by pmqs (Friar) on Jan 12, 2011 at 13:44 UTC
    That code will work fine, but here is a variation that means you don't need to uncompress the complete outer zip into memory before accessing the inner one.
    use warnings; use strict; use IO::Uncompress::Unzip qw(:all); my $file1 = "all.zip"; my $file2 = "1.zip"; my $first = new IO::Uncompress::Unzip $file1 or die "Cannot open $file1: $UnzipError\n"; my $output; unzip $first => \$output or die "Cannot open $file2: $UnzipError\n";
Re^4: Reading a .txt file under 2 levels of compression
by LazyIntern (Initiate) on Jan 13, 2011 at 01:04 UTC
    Thanks bart for code. It is working! I do have another question regarding the following script: unzip $file, \$inner, Name => '1.zip'; What does \$inner mean? Unzipping file into a temp location called inner?
      When I wrote unzip I wanted to allow flexibility on where it obtained it's input and where it sent its output. Currently the input and output paramers can be a filename, filehandle or in-memory.

      So, for example

      my $inner; unzip "my.zip" => \$inner; # remove all whitespace $inner =~ s/\s+//g; print $inner;
      This will uncompress the contents of the file "my.zip" and write the uncompressed data into the variable $inner.

      The code then makes use of the uncompressed data in this case to remove all whitespace, then print it.

      \$inner is a reference to the scalar $inner. It allows programmers to change the content of the variable $inner without explicitly mentioning it by name in the source. You can just as well use a different variable and it'll work the same. For example:
      $apples = 10; $pears = 6; take_one(\$apples); # take one apple take_one(\$pears); # take one pear print "I've still got $apples apples and $pears pears.\n"; sub take_one { my $ref = shift; # a reference $$ref-- # access the value of the referenced scalar }
      This prints:
      I've still got 9 apples and 5 pears.

      For more info, check out perlreftut and perlref.

      It's easy for a programmer to detect if a value is a reference: just use ref: it'll return an empty string for a normal string, and "SCALAR" for a reference to a scalar.

      It's a convention among module authors to use a reference to a scalar if you want to actually use the string value as data, instead of as a file name from which you'll read the contents; for example in the various HTML parsing modules.

        I see. Usually for Methods I would simply read what it requires and what outputs it will give. In the case of Zip, I couldnt find any sources that says the code is valid (like unzip $file, \$inner, Name => '1.zip'; , it still looks wrong to me but it works). Thanks once again.