How to zip only files and not the full path

755 Views Asked by At

I'm trying to zip up image files using Archive::Zip. The files are in Data/Temp/Files When I loop through the logs in the directory and add them to the zip file, I end up with the folder hierarchy and the image files when I only want the image files.

So the zip ends up containing:

Data
  └Temp  
    └Files
       └Image1.jpg
        Image2.jpg
        Image3.jpg

When I want the zip file to contain is:

Image1.jpg
Image2.jpg
Image3.jpg

Here is the script I'm running to test with:

#!/usr/bin/perl
use Archive::Zip;

$obj = Archive::Zip->new();   # new instance

@files = <Data/Temp/Files/*>;

foreach $file (@files) {
    $obj->addFile($file);   # add files
}

$obj->writeToFileNamed("Data/Temp/Files/Images.zip");
2

There are 2 best solutions below

0
On BEST ANSWER

Use chdir to change into the directory:

use Archive::Zip;

$obj = Archive::Zip->new();   # new instance

chdir 'Data/Temp/Files';
@files = <*>;

foreach $file (@files) {
    $obj->addFile($file);   # add files
}

$obj->writeToFileNamed("Images.zip");
0
On

The names and paths of zip archive members are completely independent of those of their real file counterparts. Although the two names are conventionally the same, AddFile allows you to specify a second parameter which is the name and path of the corresponding archive member where the file information should be stored

You can achieve the effect you're asking for my using basename from the File::Basename module to extract just the file name from the complete path

This program demonstrates. Note that it is essential to use strict and use warnings at the top of every Perl program you write

use strict;
use warnings;

use Archive::Zip;
use File::Basename 'basename';

my $zip = Archive::Zip->new;

for my $jpg ( glob 'Data/Temp/Files/*.jpg' ) {
  $zip->addFile($jpg, basename($jpg));
}

$zip->writeToFileNamed('Data/Temp/Files/Images.zip');