Reputation: 16305
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
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
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
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