Perl: управление путями в Windows - PullRequest
4 голосов
/ 20 ноября 2010

Мне трудно работать с путем, содержащим не английские символы (Activestate Perl, Windows XP).Как открыть, записать, скопировать и т. Д. Файл, находящийся по пути с допустимыми греческими / русскими / французскими символами?Допустим, каталог, в который я хочу скопировать файл text.txt: C:\Documents and Settings\στα\Desktop

use File::Spec;
my $save = File::Spec->canonpath( $mw->chooseDirectory() );

my $file = catfile($save , "renamed_text.txt");

my $input = "üüü\text.txt";
copy ($input, $file) or die "File cannot be copied.";

Ответы [ 5 ]

3 голосов
/ 23 декабря 2010

У меня нет привилегий голосовать за ответ Криса Долана, но я решил эту проблему для имен путей здесь, в Японии, с тем же решением, основанным на Win32 :: Codepage .

Это, вероятно, нуждается в подтверждении, но я думаю, что Perl предполагает UTF8 для всех путей не-ASCII. В Linux и OS X это работает нормально, потому что пути к ОС закодированы в UTF8. Но в более старых версиях Windows (до Windows 7?) Имена путей кодируются в локали страны (например, Shift-jis здесь, в Японии). Таким образом, все вызовы Perl, которые возвращают имена путей с не-ASCII-символами, запутались.

Решение, которое я использовал, состояло в том, чтобы найти кодировку локали с использованием Win32: Codepage и затем кодировать ее в UTF8 при чтении файлов. Затем при записи (или обновлении) файлов я декодирую обратно в кодировку локали.

2 голосов
/ 19 декабря 2010

У меня была такая же проблема в проекте несколько лет назад (наше GUI-приложение, упакованное в PAR, должно было работать в кодировке Shift-JIS).Я испробовал множество методов, чтобы Perl 5.8 сделал это правильно автоматически.В конце концов, мое утомительное, но эффективное решение состояло в том, чтобы закодировать КАЖДЫЕ имя файла непосредственно перед передачей его встроенным.

Сначала настройте служебную функцию:

use Encode;
use Win32::Codepage;
my $encoding = Win32::Codepage::get_encoding() || q{};
if ($encoding) {
    $encoding = Encode::resolve_alias($encoding) || q{};
}
sub encode_filename {
    my ($filename) = @_;
    return $encoding ? encode($encoding, $filename) : $filename;
}

Затем используйтеэто везде :

next if (! -d encode_filename($tmpldir));
my $file = SWF::File->new(encode_filename($dest));
@entries = File::Slurp::read_dir(encode_filename($srcdir));
etc...

Я даже написал небольшую проверку, чтобы убедиться, что я использовал ее везде!

egrep "\-[a-zA-Z] |open[^_]|[^ ]parse|unlink|symlink|mkdir[^_]|mkpath|rename[^\']|File::Copy::copy|rmtree|getTemplate[^D]|write_file|read_file|read_dir" *.pl `find lib -name '*.pm'` | grep -
v encode_filename | egrep -v '^[^:]+: *(\#|_announce|debug)'

Если вы пропустите хотя бы одну, выполучить предупреждение «Широкий символ» во время выполнения ...

0 голосов
/ 26 ноября 2015

У меня также были проблемы с UAC (контроль доступа пользователей) в Windows 7 и новее. Наконец, я узнал, что доступ к необходимому ключу реестра имеет только права на чтение со времен Windows Vista. Вы можете легко исправить Win32 :: Codepage для работы без прав администратора, если откроете файл в своем любимом редакторе и замените:

  $codekey = Win32::TieRegistry->new($CODEPAGE_REGISTRY_KEY,
                                     { Delimiter => "/" }
                                    );

  $codekey = Win32::TieRegistry->new($CODEPAGE_REGISTRY_KEY,
                                     { Access=>"KEY_READ", Delimiter => "/" }
                                    );

Это помогло в моей установке.

0 голосов
/ 06 июля 2013

Я обнаружил, что должен был отключить UAC ( Контроль доступа пользователей ) в Microsoft Windows Vista, прежде чем смог успешно установить Win32::Locale или Win32::Codepage.(Спасибо, Крис Долан, за написание последнего модуля.)

0 голосов
/ 20 ноября 2010

Нативные функции Perl в этом случае не могут быть использованы. Используйте функции в модуле Win32, которые поддерживают символы Unicode. Win32 был впервые выпущен с Perl v5.8.7.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...