Peter Schuetze
Peter Schuetze

Reputation: 16305

Perl Archive::zip -- file doesn't get added

I am traversing a directory tree (subversion backup) and add every file and directory that I find to a zip file. This works pretty slick. However two files are missing.

sub zipFolder
{
    my $dir = 'D:\\SVN-Backup\\EnterpriseDataRepository\\20110502-0630';
    my $zip = Archive::Zip->new();
    my $zipped = $zip->addDirectory($dir);
    $zipped->desiredCompressionLevel( 9 );
    $zipped->desiredCompressionMethod( COMPRESSION_DEFLATED );
        print "Before find\n";
    find(\&zip_file, $dir);
    print "after find\n";
    die 'write error' unless $zip->writeToFileNamed('D:/SVN-Backup/CCBuild/backup.zip' ) == AZ_OK;

    sub zip_file 
    {
          print $File::Find::name;
          if ( -d $File::Find::name ) { # just grab directories, not files.
            $zip->addDirectory($File::Find::name);
            print " : dir\n";
         } else { #zip files
           print " : file\n";
           $zip->addFile($File::Find::name) != AZ_OK ||  print "couldn't add file \n";
         }

    }
}

The file D:\SVN-Backup\20110502-0630/db/revprops/0/0 will not be added to the zip archive. Any idea what I can do to get the this file added as well?

...
D:\SVN-Backup\20110502-0630/db/uuid : file
D:\SVN-Backup\20110502-0630/db/revprops : dir
D:\SVN-Backup\20110502-0630/db/revprops/0 : dir
D:\SVN-Backup\20110502-0630/db/revprops/0/0 : file
D:\SVN-Backup\20110502-0630/db/revprops/0/1 : file
D:\SVN-Backup\20110502-0630/db/revprops/0/10 : file
...

Congrats to Andy for his contribution. He solved the Problem.

A related bug: rt.cpan.org/Public/Bug/Display.html?id=27463, but that's only about files, not directories. What version of Archive::Zip do you have?

I have perl 5.8.8 which does seem to be older than the fix.

Upvotes: 2

Views: 2580

Answers (3)

Bohdan
Bohdan

Reputation: 17193

You can add the whole directory recursively:

    my $zip = Archive::Zip->new();
    $zip->addTree('C:\~~~\some dir', 'new name for dir');
    $zip->writeToFileNamed( 'C:\~~~\great.zip' );

This will add directory and of it's content to zip archive with all relative preserved.

Upvotes: 0

Andy
Andy

Reputation: 4866

I found CPAN bug 27463, which would explain the issue if you have an older version of Archive::Zip (<= 1.20, as best I can tell from CPAN).

As both snoopy and I guessed, the bug was due to the filename "0" being false when used as a condition.

Upvotes: 3

dwarring
dwarring

Reputation: 4883

I'm having a look at the source code for Archive::Zip. This addFile method is in Archive::Zip::Archive, which in turn calls addMember in the same source file:

sub addMember {
    my $self       = shift;
    my $newMember  = ( ref( $_[0] ) eq 'HASH' ) ? shift->{member} : shift;
    push( @{ $self->{'members'} }, $newMember ) if $newMember;
    return $newMember;
}

This sub will fail when $newMember is '0' (false). I think Archive::Zip may need an RT ticket submitted against it, with a patch to fix the above.

Upvotes: 2

Related Questions