in reply to Getting IO::Compress::Zip to include directory entries (on Windows)

Looking the FilterName option portion of the documentation for IO::Compress::Zip, I was able to figure out a syntax that appeared to work for me.

I created a directory named 'test_dir' and created two text files in that directory. Then I used the following code:

use strict; use warnings; use IO::Compress::Zip qw(:all); my $outfile = "test.zip"; my $dir = "test_dir"; zip [ <$dir/*.txt> ] => $outfile, BinModeIn => 0 or die "zip failed: +$ZipError\n";

When I ran the code, it created a zip file that had a directory named 'test_dir', which in turn contained the two text files. This was done on Windows 7 using Strawberry Perl 5.20.0 and IO::Compress::Zip 2.064.

Hopefully the code above will help point you in the right direction for what you're trying to do.

  • Comment on Re: Getting IO::Compress::Zip to include directory entries (on Windows)
  • Download Code

Replies are listed 'Best First'.
Re^2: Getting IO::Compress::Zip to include directory entries (on Windows)
by hilitai (Monk) on Feb 03, 2016 at 00:35 UTC

    Thanks! But I guess I wasn't clear enough. I can already include all the files, in whatever directory; what I'm trying to do is include the directory entry itself, like a native zip program would do.

    For example, here's the output of Zip 3.0:

    C:\Temp\ztest>zip -r test2.zip WEB-INF adding: WEB-INF/ (208 bytes security) (stored 0%) <-- dir, not file adding: WEB-INF/deploy/ (208 bytes security) (stored 0%) <-- ditto adding: WEB-INF/deploy/client/ (208 bytes security) (stored 0%) adding: WEB-INF/deploy/client/rpcPolicy/ (208 bytes security) (store +d 0%) adding: WEB-INF/deploy/client/rpcPolicy/manifest.txt (208 bytes secu +rity) (deflated 4%) <-- first actual file

    So it's stored the directory entities and information (including modification times) as well as the files. That's what I'm trying to emulate.

    I've done some more digging around, and I'm beginning to think that IO::Compress::Zip might just not do what I want. Also, I didn't think that Archive::Zip was in the core libraries, but it looks like it has been since v 5.12 or so, maybe. (On the other hand, I have to work with some very old systems.)

    I might not even need this ability for what I want to do, but the closer I can come to a Real Zip File on output, the better.

      what I'm trying to do is include the directory entry itself

      In the docs it says filenames only

      If $input is an array reference, each element in the array must be a filename. The input data will be read from each file in turn. The complete array will be walked to ensure that it only contains valid filenames before any data is compressed.
      poj

        IO::Compress::Zip cannot write directories (without jumping through a lot of hoops) by design.

        I do have another module, called Archive::Zip::SimpleZip (it actually uses IO::Compress::Zip under the hood), that can create directories.

        Here is a example of how to use it

        use strict ; use warnings; use Archive::Zip::SimpleZip; my @dirs = ("WEB-INF"); my $zip = Archive::Zip::SimpleZip->new("test.zip"); $zip->add($_) for @dirs; $zip->close();

        and here is what the commandline unzip this about the zip file

        $ unzip -l test.zip Archive: test.zip Length Date Time Name --------- ---------- ----- ---- 0 02-03-2016 12:58 WEB-INF/ --------- ------- 0 1 file
      But I guess I wasn't clear enough.

      Actually, I think that I understood you correctly, but I probably failed to properly describe what I tested.

      Here's the file and directory layout of what I tested (and the contents of test.pl is the code from my previous post):

      C:\test\test.pl C:\test\test_dir\file1.txt C:\test\test_dir\file2.txt

      After running perl test.pl, I got a new file: C:\test\test.zip. Here's the contents of test.zip:

      test_dir\file1.txt test_dir\file2.txt

      As you can see, the file and directory structure was fully and correctly added into the new zip file. And a quick check shows that the two text files' modification date/time stamp is preserved in the new zip file too. I believe that is the basic idea of what you are trying to do. However, I suspect that you'll need to make modifications to the code that I posted in order to fully do what you're trying to do.