Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I read file handles within a zip file? 1

Status
Not open for further replies.

linctus

Technical User
Jul 14, 2003
14
AU
Obviously I am a rank beginner but I love the challenge!
I am not doing this for any other reason than to teach myself perl.

Anyway,
I have a zip file that contains various PDF files.
I have tried to read the zip to capture the file names and display them on screen using the following,

open (OUTF, "accnt.zip");
@data = <OUTF>;
close (OUTF);
foreach $line (@data)
{
print &quot;------&quot;. $line;
}
$count =@data;
print &quot;$count lines in file!\n&quot;;

I get...
0 lines in file

I know I should declare that I am trying to read a zip file.
I have read most of CGI 101 & programming Perl but neither make any mention of zip files.
I know I'm a 'dill' but can someone put me out of my misery?

 
You need to use the module Archive::Zip. The doc file included with it is filled with LOTS of information and it took me a while to muddle through it, but I pounded out a simple script that should give you what you are looking for. If you figure out more advanced things from the docs on your own - great job. If you want more help, just let me know.

Here is the script:

use Archive::Zip;
my $zipFile = Archive::Zip->new();
die &quot;Can't read zip file\n&quot; unless $zipFile->read( 'c:/test.zip' ) == 0;
my @files = $zipFile->memberNames('c:/test.zip');
foreach $file (sort @files) {
print &quot;$file\n&quot;;
}
 
Thanks raklet,
for you prompt reply / support.
I checked & the archive::zip module isn't loaded on my server. I'll do that and let you know how I get on.
I thought I was missing a declaration.


 
Once again thanks raklet (mis)
all you suggested worked fine once i installed the module.
one last stumbler though (& i have spent the last two days trying to find the answer), within Archive::zip there is the option to extract members from the zip file like below;

$zip->extractMember($memberName);

do you know how to specify a path for the extraction?
The above command only extracts the member specified to the folder where the cgi script lives :( I have serched CPAN without luck.
 
Use this code:

use Archive::Zip;
my $zipFile = Archive::Zip->new();
die &quot;Can't read zip file\n&quot; unless $zipFile->read( 'c:/test.zip' ) == 0;
$zipFile->extractTree('','','c:/extract');

The line you are interested in is the last one:

$zipFile->extractTree('','','c:/extract');

Here is what it does:

The first set of blank '' tells the program to extract all of the files in the zip archive. You can place pattern matches or file names between the '' to tell the program to extract specific items.

The second set of blank '' tells the program what to rename the extracted files as. In this case, blank means don't rename it to anything. If you had a file in the zip archive called test.txt and you were to specify 'new' in the second set of '' then the extracted file would be called newtest.txt.

The third set of '' tells the program where to extract the files to.

Cheers
 
Thank you again raklet,(in anticipation) i'm sure it will solve that part of my challenge
:)

- exciting 'stuff' -
 
Thanks again raklet for the help thus far...
The script offered works but...
When I place the path in between the last '' regardless of whether I store the path to a $ or type the whole destination path in as a url or dir path the code places the extracted files into the cgi-bin in the same folder as the script.
The zip is stored lower down in a public folder and I want to either extract one member or all (don't care at this stage) into the same folder or a sub folder in the public area.
I have to do this because of server permissions set up, no public read access to cgi-bin, don't want that, & don't want the cgi in the public folder area.

$zipFile->extractTree('','','/my/path/');
doesn't seem to read the destination path, any Ideas??
 
Hmmm, not sure why it would behave this way. I have tested it extensively on Win32 platform and it has worked fine. I have tried extracting into the same folder as the zip, from one folder to another, etc.

Since playing with it, I have found that you can also specify the extract like this:

$zipFile->extractTree('','c:/extract/');

The first '' still does the same thing. It tells the program to extract all files. But, I have found that you can not only play with file names in the second set of '' but you can specify locations. It all depends on the syntax.

First I will explain my test environment.

Zip file: test.zip
File inside of test.zip:
test1.txt
test2.txt
test3.txt

Okay, in the second set of '', if I specify:

'c:/extract'

then I will get three files at the root of c: (doesn't matter where I the zip was located). The files will be called: extracttest1.txt, extracttest2.txt, and extracttest3.txt.

However, if I specify:

'c:/extract/' (note that I put and ending slash)

then I will get three files located in c:/extract that are named test1.txt, test2.txt, and test3.txt. I tested this with both the folder already being there and with it not being there. If the folder &quot;extract&quot; already existed, great. If it did not exist, then it was created for me.

You can continue to extend this syntax down as many levels as you need.

If this doesn't work you may want to check file permissions. I haven't done anything with cgi so I am not sure about how it behaves in allowing the perl script to interact with folders outside of its own folder, but it seems that I recall something about this being the case.

Give this a try and let me know if it works any better for you.


 
You got it!!!
$zipFile->extractTree('','/home/my/path/to/whatever/');
worked fine :)
the odd thing though, if I declare the path in a Scalar
$mydir = &quot;/home/my/path/to/whatever/&quot;;
and have
$zipFile->extractTree('','$mydir');
Zip file: test.zip
File inside of test.zip:
test1.txt
test2.txt
test3.txt
etc.

the files are created in the same folder as the .cgi script (not the folder intended) and literally have the names
$mydirtest1.txt
$mydirtest2.txt
$mydirtest3.txt
etc.

the scalar name ($mydir) is read as just text not a scalar.

By the way this is run on Perl v5.6.1

Cheers!
ps. I have learned something else from your raklet, I need to be more adventurous when trying variations with script.

I looked at the example you gave,
$zipFile->extractTree('','','c:/extract');
and tried a few different things but didn't even consider trying the paths in different areas of the code.

Good work :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top