CC: | adamk [...] cpan.org |
Subject: | A workaround for unicode support in Archive::Zip 1.30 |
Hi,
I am using Archive::Zip module version 1.30. But in our project we have
a requirement of having to create zip files with file names in non-
english languages too.
I looked at 1.31 but since it is a developer release, our company does
not allow it to be used in production code.
By looking at the source files of Archive::Zip 1.31 for files
Archive.pm and Member.pm, found that the difference is in passing the
filename using Win32::GetLongPathName and bitwise OR'ing the 'bitFlag'
with 0x0800 for the zip header.
With this info, I changed my code to call addFileOrDirectory like this:
$member = $zip->addFileOrDirectory( Win32::GetANSIPathName($filename),
encode_utf8( Win32::GetLongPathName($filename) ));
$member->{'bitFlag'} |= 0x0800;
With this bit of code change, I am able to add files with non-english
file names to a zip archive with Archive::Zip version 1.30.
Could you kindly advise if this could be a workaround or if there is
anything i'm missing?
I have attached my source file.
My apologies if I should not have raised a bug for this. I thought this
could be the best place to get advise from authors directly.
Subject: | zip.pl |
use Win32::OLE qw(in);
use Data::Dumper;
use Archive::Zip;
use Archive::Zip::Member;
use Encode qw(decode encode);
use File::Find::Rule;
require Win32;
require Encode;
Encode->import( qw{ encode_utf8 decode_utf8 } );
use String::Random;
$random = new String::Random;
local $Archive::Zip::UNICODE = 1;
print "Archive zip version = " . $Archive::Zip::VERSION . "\n";
$zip = Archive::Zip->new();
Win32::OLE->Option(CP => Win32::OLE::CP_UTF8);
$obj = Win32::OLE->new('Scripting.FileSystemObject');
unlink "chinese.zip";
$folder = $obj->GetFolder(".");
$collection = $folder->{Files};
foreach $value (in $collection)
{
$filename = %$value->{Name};
print "File name = " . Dumper($filename) . "\n";
print "ANSI Path name = " . Win32::GetANSIPathName($filename) . "\n";
print "Long Path name = " . encode_utf8( Win32::GetLongPathName($filename) ) . "\n";
$file = $obj->GetFile("$filename");
print (Win32::OLE->LastError() || "success\n\n");
$member = $zip->addFileOrDirectory( Win32::GetANSIPathName($filename),
encode_utf8( Win32::GetLongPathName($filename) ));
$member->{'bitFlag'} |= 0x0800;
}
$zip->writeToFileNamed("chinese.zip");