Archive::Zipでのshiftjis変換でハマる

* Archive::Zipのバージョン1.33現在

Archive::Zipを使ってzipファイル作る際にwindows環境を考えてshiftjisに文字コード変換した上で作成しようとしたらハマってしまったのでメモ。

my $zip = Archive::Zip->new;
$zip->addTree($dir);

for my $member ( $zip->members ) { 
    my $filename = $member->fileName; 
    Encode::from_to($filename, "utf8", "shiftjis");  
    $member->fileName($filename); 
}

こんな感じで使っていたんですが、どうやら一部のファイル名が文字化けしていた模様。
一部のファイル名とはshifjisで2バイト目に0x5c(\)を含む文字。

ーソЫⅨ噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃濬畚秉綵臀藹觸軆鐔饅鷭偆砡纊犾

このあたり。


原因は、Archive::Zip::Member->fileName

sub fileName {
    my $self    = shift;
    my $newName = shift;
    if ($newName) {
        $newName =~ s{[\\/]+}{/}g;    # deal with dos/windoze problems
        $self->{'fileName'} = $newName;
    }
    return $self->{'fileName'};
}

これが\を置換しているせいでした。

だからこの関数を使わずに

my $zip = Archive::Zip->new;
$zip->addTree($dir);

Encode::from_to( $_->{"fileName"}, "utf8", "shiftjis" )
    for $zip->members;

のように直接変換してしまえば文字化けはおきないです。


Archive::Zipでのshiftjis変換でハマる - 城好きwebプログラマーの生態メモ - 仕事編