[Moscow.pm] Создание zip-архива с русскими именами файлов через IO::Compress::Zip

Oleg Alistratov ali на ali.org.ua
Ср Окт 2 04:30:20 PDT 2013


Это не проблема IO::Compress::Zlib (и не проблема Archive::Zip).
В твоем случае это проблема с 7zip. Например, у меня твой скрипт генерирует архив,
который отлично показывается unzip-ом со всеми буквами в имени файла:

[15:26:18]  local:~/enigmas/zip-rus% unzip -l result.zip
Archive:  result.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        8  10-02-13 15:25   русское имя.txt
 --------                   -------
        8                   1 file

Явление это проистекает из того, что формат zip достаточно старый, при его создании никто не заботился
указанием кодировок в именах members. Поэтому разархиваторы додумывают уже кто на что горазд.
Скорее всего, 7zip предполагает найти имена в кодировке cp866, попробй конвертнуть в нее.


02.10.2013, 13:55, "Максим" <monk на nuked.su>:
> Доброго дня.
>
> Буду рад если кто-то поможет разобораться в задаче создания zip-архива с
> русскими именами файлов в нём. Архив создаётся и читается под linux.
> Версия IO::Compress::Zlib свежая. Все что нашел в гугле уже попробовал,
> ничего не помогает.
>
> Есть пример скрипта (набрано в utf-8), который создает тестовый архив с
> одним файлом. Если сделать его имя русским, при распаковке 7z выдаёт
> вместо имени файла крокозябры.
>
> cat pack.pl | sed '2,$s/^ *#.*//'
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Encode;
>
> use IO::Compress::Zip qw(zip $ZipError) ;
>
> my $filename = 'русское имя.txt';
>
> my $z = new IO::Compress::Zip 'result.zip', { name=> $filename,
> CanonicalName => 1}
>   or die "zip failed: $ZipError\n";
>
> $z->print("Content\n");
>
> $z->close;
>
> Крокозябры похожи на те что вылезают при конкатенации символьных utf-строк
> с байтовыми строками. Если добавить принудительный decode, проблема не
> уходит.
> cat pack.pl | sed '2,$s/^ *#.*//'
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Encode;
>
> use IO::Compress::Zip qw(zip $ZipError) ;
>
> my $filename = 'русское имя.txt';
> $filename = decode('utf8', $filename );
>
> my $z = new IO::Compress::Zip 'result.zip', { name=> $filename,
> CanonicalName => 1}
>   or die "zip failed: $ZipError\n";
>
> $z->print("Content\n");
>
> $z->close;
>
> Вывод листинга файлов 7z в обоих случаях такой
> 7z l result.zip
>
> 7-Zip 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
> p7zip Version 9.20 (locale=en_US.utf8,Utf16=on,HugeFiles=on,4 CPUs)
>
> Listing archive: result.zip
>
> --
> Path = result.zip
> Type = zip
> Physical Size = 174
>
>    Date      Time    Attr         Size   Compressed  Name
> ------------------- ----- ------------ ------------  ------------------------
> 2013-10-02 14:48:14 .....            8           10  Ñ€ÑƒÑÑÐºÐ¾Ðµ
> имя.txt
> ------------------- ----- ------------ ------------  ------------------------
>                                      8           10  1 files, 0 folders
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org

-- 
Oleg Alistratov


Подробная информация о списке рассылки Moscow-pm