Home: Perl Programming Help: Intermediate:
IO Error while using Archive::Zip


Sep 6, 2011, 11:56 AM

Views: 3761
IO Error while using Archive::Zip

This is a perl script I wrote to do a find replace in all files in a subdirectory. That part works. I found out though, that all these files will be zipped. So I'm trying to look into zipped files and do a find replace without manually unzipping and rezipping them. I'm trying to use Archive::Zip but every time I run it I get

.I0 error: read failed : Is a directory 
at Program.pl Line 23
read error at Program.pl Line 37

Here is my full perl script.

use warnings; 
use File::Find;
use Archive::Zip qw( :ERROR_CODES );

my $zippeddir = '/export/'; #Directory of <>
my $doctype = 'xml';
my @mapping=[];
#This block takes mapping csv and loads it into cache as a Multidimensional array
open(MAPPING,'/export/mapping.csv');#this should be the mapping doc. The way this script is current set up is with values "1,2,3,4" where 1 and 2 are values found in <> and 2 and 3 are the values they will be changed to for <>.
push @mapping, [ split /,/ ];
close MAPPING;
#print join "\n", map {ref $_ ? join ', ', @$_ : $_} @mapping ;
my $size = scalar @mapping; #size is counting the rows of @mapping plus 1 (ex if 2 rows then $size=3)
#print "\n$size\n";
find(\&replaceInFile,$zippeddir); #runs File::Find API on zippeddir using criteria defined in replaceInFile subroutine. In File::Find API $_ is the variable for the current file.
print "Finished";
#---------- SUBROUTINES----------------
sub replaceInFile
my @mapping3;
my $find1;
my $find2;
my $replace1;
my $replace2;
my $file = $_
my $zipfile = Archive::Zip->new($file);
unless ( $zipfile->read( $file ) == AZ_OK ) {
die 'read error';
#print "$File::Find::dir\n\n"; #prints the current directory found by find
return unless (/new2\.$doctype$/i); #new2 is the string before .xml in file name
local @ARGV = $file; #sets printing to file
local $^I = '.bac'; #Makes backup of file turn OFF for <> files
while( <> ) #while loop for every line in current file
my $line="";
$line=$file; #sets $line as $_, which in Find::Find is the current file
my $count = 1;
while ($count < $size) #since $size is the number of lines plus 1, the while loop only runs until $count is one less than $size
if (($mapping[$count][0] eq $mapping[$count][2]) && ($mapping[$count][1] eq $mapping[$count][3])) #If mapping is same in both systems it iterates count and skips.
#print "WORKS\n";
#print "BROKE\n";
#print "SUBWHILE$count\n";#prints the $count
#print "$find1\n";
#print "$replace1\n";
#print "$find2\n";
#print "$replace2\n";
#print "s/$find1/$replace1/ig";
$line=~s/$find1/$replace1/ig; #first term is the term to FIND second terms is term to be REPLACED


print "$line"; #Does actual printing to file



Sep 6, 2011, 12:45 PM

Views: 3754
Re: [zigy221] IO Error while using Archive::Zip

Check to make sure the " my $file = $_ " contains the zip file name to be read by archive thats what the error message seems to be is that file find might be returning something other the what is expected.


Sep 8, 2011, 2:01 AM

Views: 3643
Re: [zigy221] IO Error while using Archive::Zip

Your forgot to annotate in your program, which lines 23 and 37 are.