I am changing a PERL code that does compression to be able to handle the zip64 extension.
the old code is using Archive::Zip module that can be used as follows.
# Create a Zip file
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
my $zip = Archive::Zip->new();
# Add a file from disk
my $file_member = $zip->addFile( 'xyz.pl', 'AnotherName.pl' );
Archive::Zip doesn't support zip64 extension and because of that I am using IO::Compress::Zip module instead.
I am looking for a way to mimic the addfFile functionality some way or another, renaming while zipping or maybe editing the archives after zipping.
I can't find any PERL module that can help me in doing so.
Is there any way in PERL to do that ?
In case there is not a direct way, can I change something in the
header of the archive file to rename its members ?
Thank you
I assume this is the same question you asked over on PerlMonks Renaming a file member in zip64 archive?
If so, here is the same reply.
Try this - it will automatically create the output file as a Zip64 compliant Zip archive if required (i.e. if the size exceed 4 Gig or you have > 64k members in the zip archive). Otherwise it creates a standard Zip archive.
use Archive::Zip::SimpleZip qw($SimpleZipError) ;
my $z = new Archive::Zip::SimpleZip "my1.zip"
or die "Cannot create zip file: $SimpleZipError\n" ;
$z->add('xyz.pl', Name => 'AnotherName.pl' );
$z->close();
If you want to force the creation of a Zip64 archive (even when the archive is small enough not to need it) add the Zip64 option when creating the Archive::Zip::SimpleZip object, like this
my $z = new Archive::Zip::SimpleZip "my1.zip", Zip64 => 1
or die "Cannot create zip file: $SimpleZipError\n" ;
I am not sure if there is a way to do it with IO::Compress::Zip, but.
Why do not you rename files before adding them to archive?
If you need to preserve original files with its names, copy the files to some temp folder, rename, and to archive and delete from temp after.
Related
I have to fix a Perl script which is having issues adding files recursively. As I am not a Perl programmer this is kinda hard for me, hope that somebody will have a clue for me.
What the script has to do is ZIP a directory from a mounted (NAS) share. I am running into the issue that the ZIP is created as expected, is a valid ZIP and does contain the directory structure of the original directory. By example, when I try to ZIP a directory like "/mounted_dir/to_zip/" which contains a sub-directory called "sub_dir" which contains a file like "filetozip.txt" I will only find the directory structure in the ZIP file. No errors are shown.
I tested it by creating a 2 pertty simple scripts to test:
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
my $zip = Archive::Zip->new();
my $dir_member = $zip->addDirectory( '/mounted_dir/to_zip/' );
unless ( $zip->writeToFileNamed('/tmp/someZip.zip') == AZ_OK ) {
die 'write error';
}
and with AddTree function:
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
my $zip = Archive::Zip->new();
$zip->addTree( '/mounted_dir/to_zip/' );
unless ( $zip->writeToFileNamed('/tmp/someZip.zip') == AZ_OK ) {
die 'write error';
}
Both with same results.
If I move the "to_zip" directory to the local filesystem, everything is working as expected. ZIP file is created with directories and files.
This has been working in the past on an older Fedora/Perl version. I had to update Fedora to a newer version because of the lack of SMB3 support in my version. With that upgrade my Perl moved to version 5.18. Archive::ZIP is at the latest 1.68 version.
When I access the directories and files on the command line I can do whatever I want with them. Create, rename, edit, remove, etc. etc. Also used the default Fedora ZIP and TAR tools, all working. So I think this is not a directory or file permission. Feels like I am missing some option in Perl / Archive::ZIP, but as said I am not a Perl progammer and do miss essential basic knowledge.
I am trying to access a text file within a zipped folder to extract a certain information, without actually unzipping the file. I am trying to use Archive::Zip. The directory structure is like Data_stats.zip--> Data_stats/ --> full_data_stats.txt. Now I tried this
use Archive::Zip;
use Archive::Zip::MemberRead;
use File::Basename;
$zip_dir=$ARGV[0];
#name =split("\\.",basename($zip_dir)); ## to get zipped folder name
$dir = Archive::Zip->new("$zip_dir");
$fh = Archive::Zip::MemberRead->new($dir,"$name[0]/full_data_stats.txt"); ##trying to reads the file giving the path and mentioning the specific file name
while (defined($line = $fh->getline()))
{
{print}
}
I see it extracting the folder but not reading in the file !!.
Regards
You are assigning to $line but printing $_; try print $line;
I have the following directory tree:
mydir/
mydir/bbb/
mydir/bbb/ccc/
mydir/bbb/ccc/myfile.txt
The file zips as follows:
bbb\ccc\myfile.txt
I want it to appear as
\ddd\myfile.txt
The command-line zip utility does not seem to have option. Is there another way, perhaps using Perl. I'm using a unix system.
If I understand you correctly then it looks like the Archive::Zip module will do what you need.
Once you have created an archive, you can use addFile to add an archive member whose path is different from the source. Like this
$zip->addFile( {
filename => 'mydir\bbb\ccc\myfile.txt',
zipName => 'ddd\myfile.txt',
} );
For instance, this program creates a zip archive and adds the contents of the current script (defined by $0) as a member called ddd\current.pl. The archive is then written to a file called current.zip. If you open that file using 7-Zip or similar then you will see ddd\current.pl.
use strict;
use warnings;
use Archive::Zip;
my $zip = Archive::Zip->new;
$zip->addFile( {
filename => $0,
zipName => 'ddd\current.pl',
} );
$zip->writeToFileNamed('current.zip');
I am new in perl script. I want to write perl which delete previous backup file and extract new backup file from dropbox and rename with specific file name.
Example:
backup location:
D:\Database\store_name\ containing .bak files
Actual folder data
D:\Database\Mahavir Dhanya Bhandar\ contain .bak file
D:\Database\Patel General Store\ containg .bak files
..so on
How can write perl script code which delete *.bak files store_recursively
2.extract new backup file from dropbox and rename with specific file name.
Have you looked into walking your file tree. http://rosettacode.org/wiki/Walk_a_directory/Recursively. Combine this with simple file operations (copying, deleting, etc.) and you should be good.
use File::Find qw(find);
my $dir = "D:\Database\Store_Name";
find sub {unlink $File::Find::name if /\.bak$/}, $dir;
and assuming that connectToDropbox() connects to your dropbox
use File::Copy;
use File::Find qw(find);
my $backup = connectToDropbox();
my $dir = "D\Database\Store_Name";
find sub {copy($backup -> getFile("file"), "newFile")} $dir;
of course, this assumes that you already can set up a connection and such to Dropbox. If not, there is a good CPAN libraryhere you can check out.
I want to rar a whole folder with Perl and Archive::Rar. For example the folder /root/pictures.
I have found only a way to rar single files.
I tried to find all files in the folder and rar them, but then I always have the whole path sticking to them (/root/pictures) in the rar archive.
I want only the /pictures folder plus its contents. Is that possible?
The folder structure of the files stored in the archive will be the same as the file names that you pass to the Add method. (Although you can add them without any containing folder at all using the -excludepaths option.)
If you chdir to the \root directory before adding the files to the archive, and specify all your files as pictures\file1.jpg etc. then the result should be as you want.
Something like this
use strict;
use warnings;
use Archive::Rar;
use autodie;
chdir '\root';
my $rar = Archive::Rar->new(-archive => 'pictures.rar');
$rar->Add(-files => [ glob 'pictures\*' ]);
Clearly you could add a path to the rar file name if you want the archive stored elsewhere.
At first you have to get a list of files from defined directory:
use File::Find;
my #content;
find( \&wanted, '/some/path');
sub wanted {
push #content, $File::Find::name;
return;
}
After that you may use the Archive::Rar to pack it.
use Archive::Rar;
my $rar = Archive::Rar->new();
$rar->Add(
-size => $size_of_parts,
-archive => $archive_filename,
-files => \#content,
);