in reply to Reading a .txt file under 2 levels of compression

The simple approach would be to decompress the external ZIP file into a temporary file, and then open that temp ZIP file.

But it would be cleaner, from a purist point of view, to skip using temp files and uncompress the ZIP file directly into RAM.

And by the looks of it, it seems IO::Uncompress::Unzip can do just that:

A top-level function, unzip, is provided to carry out "one-shot" uncompression between buffers and/or files. (emphasis mine)

unzip $input => $output [, OPTS]
unzip expects at least two parameters, $input and $output.
If $input is a scalar reference, the input data will be read from $$input.
If $output is a scalar reference, the uncompressed data will be stored in $$output.
For OPTS, you'll need at least this — because a ZIP file can contain lots of files, and you have to select one:
Name => "membername"
Open "membername" from the zip file for reading.

Replies are listed 'Best First'.
Re^2: Reading a .txt file under 2 levels of compression
by LazyIntern (Initiate) on Jan 12, 2011 at 00:25 UTC
    that is exactly what I want to avoid: unziping temp files. I don't quite get your explanation. Does the code unzip $input => $output , OPTS work for the straight forward solution of unzipping all files or does it extract only the zip file inside the compiled zip file? A bit more code would greatly help in my understanding. Thank you for response!
      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";
        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";
        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?
      I think you'll find that reading the documentation (perldoc IO::Uncompress::Unzip) will help your understanding even more than being spoonfed its content.

      Or, at a minimum, doing so and demonstrating that you have with some question not clearly answered there, would at least belie your chosen nick.

        I have written a code to read a file in one level of compression. I have been searching through to look at how I can read a file under 2 level of compression. Its the methodology I required which can be advance such as hash tracking. The nick is more for fun ;)