views:

215

answers:

5

PROBLEM FOUND. I'm leaving the question here, though, in case others run into the same problem I ran into.

It looks like I encountered a bug or a weird feature in WinZip 11. When I double click the test2.zip file to see its contents, WinZip tells me the path to the data file is "allcapsname" in lower case, but when WinZip extracts the archive (from a right-click Extract to here menu), it actually creates the "ALLCAPSNAME" directory properly. I was complaining about a problem I thought I was having with Archive::Zip and it was a WinZip problem the whole time. Thanks to all who helped figure out what was wrong.

Turns out that to get the path to show up in WinZip file while using Archive::Tar, you need this line in your code to force Archive::Tar to deviate from strict POSIX compliance: $Archive::Tar::DO_NOT_USE_PREFIX = 1;

ORIGINAL QUESTION: I've found a handful of various Perl modules so far that appear to be capable of creating ZIP or GZIP or TAR or TGZ archive files from within my Perl scripts, but I haven't actually had complete success from any of them. Why is this so hard? Is it because I'm on a Windows machine? (I've wasted about 4 hours on this seemingly simple task so far and am really getting frustrated.)

When I tried Archive::Tar I had success creating the archive file, but I was not able to get the paths to any of my files included in the tarball for some reason or another. I tried a bunch of different things in my code and my tarball always showed the files in there with empty paths. (I'm looking at my tarballs using WinZip.)

When I tried Archive::Zip I had more success and I got the actual directory path to my files included in the archive file. The only problem was that my path to my files was somewhere along the way changed from upper case to lower case. Why did it change the case of my directory? I want the actual directory name to remain exactly as it was.

I tried a few other modules without any success. I can't even get the sample code from Archive::Builder to even compile.

ORIGINAL QUESTION ADDENDUM:

I have finally been able to create a minimal executable script that clearly demonstrates my 2 problems that I described above regarding Archive::Zip and Archive::Tar.

use strict;
use warnings;
use Archive::Zip;
use Archive::Tar;

print "Starting...\n";

# Archive::Zip Synopsis (relative path to directory)
my $zip1 = Archive::Zip->new();
$zip1->addFile( 'MyArchiveFiles/file1.txt' )
    or die 'unable to add file to archive';
$zip1->writeToFileNamed('test1.zip');

# Archive::Zip Synopsis (with ALL CAPS DIRECTORY NAME)
my $zip2 = Archive::Zip->new();
$zip2->addFile( 'ALLCAPSNAME/file1.txt' )
    or die 'unable to add file to archive';
$zip2->writeToFileNamed('test2.zip');

# Archive::Tar Synopsis (relative path to directory)
my $tar3 = Archive::Tar->new;
$tar3->add_files( 'MyArchiveFiles/file1.txt' )
    or die 'unable to add file to archive';
$tar3->write('test3.tar');

print "Finished successfully!";

This script creates 3 archives. The first archive contains the data file with the appropriate path of "MyArchiveFiles\". My problem occurs when my directory name is all caps. The second archive contains the data file, but the path in the archive file is not "ALLCAPSNAME\" as expected ... it is "allcapsname\". This is a problem for me. Why did it change the case of my path and how can I force it to leave it alone?

The third archive contains the data file but it contains an empty path for that file. This is a problem for me. I need the path to be in the archive so that when I unpack the archive the files are extracted into the appropriate directory structure.

+1  A: 

I hear your frustration of simple things sometimes with perl on win32. If all else fails, just get a command-line version of 7-zip doing what you want, and then do a system() call to it.

Kev
How is this answering anything?
Sinan Ünür
Sometimes the answer is to punt. It's not a bad suggestion, even if just in the short term to get things working while you figure out the rest. I've had my own struggles with Archive::Zip in the past couple of weeks and briefly did just as Kev described.
brian d foy
Oh, don't get me wrong, I am all for invoking command line programs rather than trying to write them. My guess, however, is that the OP's problems are not really related to `Archive::Zip` or `Archive::Tar` or even Windows. So, we basically have a post that says *Windows sucks* and another one that says, *I feel your pain*, but no idea what really is wrong and why it is wrong and how it can be fixed. So, my recommendation is for Kurt W. Leucht either to post his complaints on his blog or to post some details here so this post has a chance of actually helping others.
Sinan Ünür
Well, working examples was what I was hoping someone would post, and it looks like Sinan's example works at first glance. I have some homework to do now to figure out what my code was doing incorrectly. Any working examples that are posted are going to help users. Then when I post what I actually was doing wrong, that might also help some users.
Kurt W. Leucht
In this case, I'm not allowed to punt because this is production code.
Kurt W. Leucht
@Sinan: I thought it answered at least the title of the OP. @Kurt: Fair enough. :)
Kev
+4  A: 

Do you have a specific question? The following code works perfectly fine on Win32:

#!/usr/bin/perl

use strict;
use warnings;

use Archive::Zip;
use File::Find;

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

find(\&wanted, $ENV{TEMP});

$zip->writeToFileNamed('test.zip');

sub wanted {
    return unless /\.txt$/;
    $zip->addFile($File::Find::name);
}

Let's run it:

C:\Temp> arc

C:\Temp> unzip -l test.zip

Archive:  test.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
      240  10-16-09 19:19   /Temp/cpan_install_Wb7z.txt
     2401  10-18-09 23:09   /Temp/perldoc_perlfunc_T4adbd85e_aec9c.txt
     2401  10-18-09 23:09   /Temp/perldoc_perlfunc_T4adbd872_bc437.txt
     2718  10-19-09 10:04   /Temp/perldoc_perlfunc_T4adc71e7_f4c64.txt
     2718  10-19-09 10:04   /Temp/perldoc_perlfunc_T4adc71f2_bf08d.txt
     2718  10-19-09 10:04   /Temp/perldoc_perlfunc_T4adc720a_a5c6a.txt
    29188  10-19-09 10:05   /Temp/perldoc_perlfunc_T4adc7226_bd834.txt
     6949  10-20-09 17:31   /Temp/perldoc_perlfunc_T4ade2c1f_d0cf8.txt
     6949  10-20-09 17:32   /Temp/perldoc_perlfunc_T4ade2c50_f2040.txt
   106763  10-19-09 10:00   /Temp/perldoc_perlop_T4adc7103_f4cab.txt
    67948  10-18-09 23:07   /Temp/perldoc_perlvar_T4adbd7d7_d8cda.txt
 --------                   -------
   230993                   11 files

Ditto for Archive::Tar.

Update: To clear up any doubt that the files were added to the archive with the correct path, note:

C:\Temp> dir *.txt
 Volume in drive C is ****
 Volume Serial Number is ****-****

 Directory of C:\Temp

2009/10/16  07:19 PM               240 cpan_install_wb7z.txt
2009/10/18  11:09 PM             2,401 perldoc_perlfunc_t4adbd85e_aec9c.txt
2009/10/18  11:09 PM             2,401 perldoc_perlfunc_t4adbd872_bc437.txt
...
Sinan Ünür
I think this is showing what the OP said, actually: that paths are not included in the archive. They look flattened, with path separators changed to underscores.
Kev
@Kev: No. The `perldoc_perlfunc_*_*.txt` files are in my `$ENV{TEMP}`.
Sinan Ünür
That seems to work. Looking at my code now to see what I did wrong.
Kurt W. Leucht
I just added to the original question example code that demonstrates the path case problem I encountered in Zip and it also demonstrates the empty path problem I encountered in Tar.
Kurt W. Leucht
Thanks for posting the working code. It was very close to my code that was not working as expected. Only my directory name was all upper case. Looks like my all caps directory name was being shown as all lower case in WinZip. Guess I found a WinZip bug or weird feature. Thanks for helping me figure out the problem!
Kurt W. Leucht
+3  A: 

Speaking as the author of Archive::Builder, it is almost certainly not what you want.

It's meant for generating ZIP files in memory using a mix of disk and code-generated content, not for archiving.

Adam Kennedy
Okay. Thanks for posting. I didn't actually understand that from reading the CPAN documentation. You might consider making that point more clear in the next revision. Also, looks like there is a period at the end of one of your lines of code instead of a semicolon in your synopsis.
Kurt W. Leucht
A: 

I am going to answer the points raised in the new information you added to the post. I ran your script. Here are the results:

C:\Temp\a> unzip -l test1.zip
Archive:  test1.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  10-21-09 13:03   MyArchiveFiles/file1.txt
 --------                   -------
        0                   1 file
C:\Temp\a\d> unzip ../test1.zip
Archive:  ../test1.zip
 extracting: MyArchiveFiles/file1.txt

C:\Temp\a\d> dir /s
...
 Directory of C:\Temp\a\d

2009/10/21  01:09 PM              MyArchiveFiles

 Directory of C:\Temp\a\d\MyArchiveFiles

2009/10/21  01:03 PM                 0 file1.txt
C:\Temp\a\d> unzip ..\test2.zip
Archive:  ..\test2.zip
 extracting: ALLCAPSNAME/file1.txt

C:\Temp\a\d> dir /s

 Directory of C:\Temp\a\d

2009/10/21  01:11 PM              ALLCAPSNAME
2009/10/21  01:09 PM              MyArchiveFiles

 Directory of C:\Temp\a\d\ALLCAPSNAME

2009/10/21  01:07 PM                 0 file1.txt
C:\Temp\a\d> tar -xvf ..\test3.tar
tar: Record size = 3 blocks
MyArchiveFiles/file1.txt

C:\Temp\a\d> dir /s

2009/10/21  01:13 PM              MyArchiveFiles

 Directory of C:\Temp\a\d\MyArchiveFiles

2009/10/21  01:03 PM                 0 file1.txt

I cut away some of the extraneous output from dir, but I hope this makes it obvious once and for all that whatever problems you are experience are not due to Windows or Perl or Archive::Tar or Archive::Zip.

For the record:

C:\Temp> perl -v

This is perl, v5.10.1 built for MSWin32-x86-multi-thread
(with 2 registered patches, see perl -V for more detail)

Copyright 1987-2009, Larry Wall

Binary build 1006 [291086] provided by ActiveState http://www.ActiveState.com
Built Aug 24 2009 13:48:26
C:\Temp> perl -MArchive::Tar -e "print $Archive::Tar::VERSION"
1.52
C:\Temp> perl -MArchive::Zip -e "print $Archive::Zip::VERSION"
1.30
C:\Temp> tar --version
tar (GNU tar) 1.21
C:\Temp> unzip -v
UnZip 5.52 of 28 February 2005, by Cygwin. Original by Info-ZIP.
Sinan Ünür
I guess I encountered a bug or a weird feature in WinZip 11. When I double click the test2.zip file to see its contents, WinZip tells me the path to the data file is "allcapsname" in lower case, but when WinZip extracts the archive (from a right-click Extract to here menu), it actually creates the "ALLCAPSNAME" directory properly. I was complaining about a problem I thought I was having with Archive::Zip and it was a WinZip problem the whole time. Thanks to all who helped figure out what was wrong.
Kurt W. Leucht
Even after extracting, I still got no directory in the test3.tar file, though. Wonder why it's working for you and we're running the same test code. I'm using ActiveState Perl and have the latest Archive::Tar module.
Kurt W. Leucht
@Kurt Is this really so hard? I am **not** using WinZip.
Sinan Ünür
I had a legitimate problem that other users on the Internet may very well experience. It is appropriate to figure out the problem and solution on this forum so that future users can quickly and easily find the solution. That's what SO is for. If you don't have the time or patience to help new users solve their problems, then please just ignore their questions. Being rude to new users is not appropriate on this forum.
Kurt W. Leucht
@Kurt It is not rude to point out that sometimes, just sometimes, the problem is not the OS, the language or the libraries. In fact, you did not come here with a problem. "Why is this so hard? Is it because I'm on a Windows machine?" You came here with a complaint. The two are different. I had to work really hard to get a specific problem description and code to go along with it.
Sinan Ünür
I disagree. I did come here with a problem. Sounds like you're sore that it turned out to be a WinZip problem. If you were using WinZip, you'd have probably run into the same problem eventually. The problem is now solved thanks to your help and others. And now future users that encounter the same problem can find it here and also find the solution right away. SO has done its job.
Kurt W. Leucht
A: 

The answer turned out to be an issue with WinZip 11. So if you're looking at your Archive::Zip files using WinZip, just ignore the fact that the all upper case paths are changed to all lower case in the WinZip GUI because when you actually unzip it, the path will be all upper case as intended.

As far as the Archive::Tar problem of not seeing any path at all in WinZip, you need to force Archive::Tar to deviate from strict POSIX compliance with the following line and then you will see the paths in WinZip:

$Archive::Tar::DO_NOT_USE_PREFIX = 1;
Kurt W. Leucht