in reply to Re^2: newbie question to archive::zip
in thread newbie question to archive::zip

it's because my $zip = Archive::Zip->new(); AND writeToFileNamed are both in the loop .. so you're not appending to the same zip object -- you're creating, adding one file, writing out to disk, and then $zip is destroyed before the next iteration. Move my $zip = Archive::Zip->new(); to before the forloop, and the write to after.
my $zip = Archive::Zip->new(); foreach $case (@items) { ... my $member = $zip->addDirectory( 'dirname/' ); $member->desiredCompressionMethod(); $member = $zip->addFile( "$file_to_zip", "$file_name" ); + } die 'write error' unless $zip->writeToFileNamed( $zip_file_name ) == A +Z_OK;
btw, are you doing use strict; and use warnings; somewhere in your code?

Replies are listed 'Best First'.
Re^4: newbie question to archive::zip
by jashv (Initiate) on Apr 14, 2006 at 19:00 UTC
    Doing that creates one zip file with the name of the last file and puts all the files in that one zip. I need something that reads the contents of the array, builds a zipfile name from those contents and just throws the tiff file in. Here is my complete code:
    #!/perl/bin -w ###################################################################### +# # # Author: # Date: # Purpose: # ###################################################################### +# ### Modules used in the script use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); ### Global Variables $fileCount = 0; $trashcan = "c:/temp/trashcan.txt"; $file_path = "c:/temp/zip"; ###################################################################### +# @files = <c:/temp/zip/*.tif>; foreach $file (@files) { $fileCount++; } print "We have $fileCount files to work with .. lets begin\n"; ###################################################################### +# foreach $file (@files) { chomp($file); $file_to_zip = "$file"; $file =~ s/\//|/g; $file =~ s/\-/|/g; $file =~ s/.tif/|/g; $file = lc($file); #here I wanted to force the case type to low +er case for consistency push @items, "$file\n"; } my $zip = Archive::Zip->new(); foreach $case (@items) { chomp($case); @values = split(/\|/,$case); $driveltr = $values[0]; $dira = $values[1]; $dirb = $values[2]; $unique_id = $values[3]; $case_num = $values[4]; $case_part = $values[5]; $tester = length($case_part); $zip_file_name = "$file_path/$case_num.zip"; if ($tester > 0) { $file_name = "$unique_id-$case_num-$case_part.tif"; $file_to_zip = "$file_path/$unique_id-$case_num-$case_part.tif +"; #$zip_file_name = "$file_path/$case_num-$case_part.zip"; } else { $file_name = "$unique_id-$case_num.tif"; $file_to_zip = "$file_path/$unique_id-$case_num.tif"; } print "to that zip file I will add $file_name\n"; #my $zip = Archive::Zip->new(); my $member = $zip->addDirectory( 'dirname/' ); #$member = $zip->addString( 'This is a test', 'stringMember.txt' ) +; #$member->desiredCompressionMethod( COMPRESSION_DEFLATED ); $member->desiredCompressionMethod(); $member = $zip->addFile( "$file_to_zip", "$file_name" ); + #die 'write error' unless $zip->writeToFileNamed( $zip_file_name ) + == AZ_OK; #sleep(2); } die 'write error' unless $zip->writeToFileNamed( $zip_file_name ) +== AZ_OK;
    and this is a sample of the files data I am reading and trying to build zip files for:
    30589-030905TEMP-ONE.tif 30590-305cv26.tif 30591-306cv26.tif 30592-304cv743.tif 30593-304cv264.tif 30594-305CV87.tif 30595-305cv87-1of2.tif 30595-305cv87-2of2.tif 30596-305mj66-1of2.tif 30596-305mj66-2of2.tif 30597-305mj65.tif 30598-398cv560.tif 30599-504cvMDL227-1of2.tif 30599-504cvMDL227-2of2.tif
    so in the example 504cvmdl227.zip it should contain both files listed at the end
      ok .. i understand what you're going after now and the problem ..

      first, change
      @values = split(/\|/,$case); $driveltr = $values[0]; $dira = $values[1]; $dirb = $values[2]; $unique_id = $values[3]; $case_num = $values[4]; $case_part = $values[5];
      to something like:
      my ($driveltr, $dira, $dirb, $unique_id, $case_num, $case_part) = spli +t(/\|/,$case);

      again, PLEASE use strict;

      Now, to approach your problem .. One way would be, in the for loop, to populate a hash w/keys of the zip_file_name's, and values of a list (or hash) of files to put in there. Then, loop over that hash and write out the zips. Here's (untested) code that uses this approach, has the above cleanup, plus additional refactoring (note the simplications/reductions):
      use strict; use warnings; use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); my $file_path = "c:/temp/zip"; my @files = <c:/temp/zip/*.tif>; my $fileCount = scalar @files; print "We have $fileCount files to work with .. lets begin\n"; my %zips; my @items = map { chomp; s#(/|-|.tif)#|#g; lc } @files; # could just +do this in the foreach parens .. foreach my $case (@items) { my ($driveltr, $dira, $dirb, $unique_id, $case_num, $case_part) = +split(/\|/,$case); my $zip_file_name = "$file_path/$case_num.zip"; my $casePartStr = length($case_part) ? "-$case_part" : ""; my $file_name = "$unique_id-$case_num$casePartStr.tif"; my $file_to_zip = "$file_path/$unique_id-$case_num$casePartStr.tif +"; print "to the '$zip_file_name' zip file I will add '$file_name'\n" +; $zips{ $zip_file_name }->{ $file_to_zip } = $file_name; } while( my ($zip_file_name, $contents) = each %zips ){ my $zip = Archive::Zip->new(); while( my ($file_to_zip, $file_name) = each %$contents ){ zip->addFile( $file_to_zip, $file_name ); } die 'write error' unless $zip->writeToFileNamed( $zip_file_name ) == + AZ_OK; }
        i'll have to give this a try, time to go home - THANK YOU, I will reply again soon