Как прочитать файл с длинным именем файла с Unicode в Perl Strawberry, не используя Win32 :: Unicode :: File? - PullRequest
5 голосов
/ 05 января 2012

У меня есть файл, расположенный в каталоге с датскими символами на компьютере с Windows XP.Я использую Strawberry Perl и хотел бы прочитать этот файл.Следующий код работает нормально:

    use Win32::Unicode::File;
    # Some code left out....
    $fname = $mw -> getOpenFile(-filetypes=>$types);
    my $fh = Win32::Unicode::File->new;
    $fh->open('<', $fname);

Процедура getOpenFile происходит из Tk.Теперь по какой-то причине Win32 :: Unicode :: File имеет некоторые неприятные побочные эффекты, с которыми я не могу жить (он съедает мою память, см. «Недостаточно памяти» с простым циклом readline Win32 :: Unicode :: File и Strawberry Perl).Теперь, если я пытаюсь открыть файл без интерфейса Win32 :: Unicode :: File, я получаю файл не найден.Причина этого заключается в том, что путь интерпретируется неправильно.Я попытался преобразовать путь в соответствии с Perl: управление кодировкой пути в Windows , которая по какой-то причине не работает.Как мне решить это?Я пробовал следующее:

    use Encode;
    # Some code left out....
    $fname = $mw -> getOpenFile(-filetypes=>$types);
    my $fh;
    open($fh, '<', encode("utf8",$fname,Encode::FB_CROAK));

, и это не работает.Есть идеи?

Пожалуйста, прости меня, если я неясен.

С уважением, Майкл

1 Ответ

5 голосов
/ 05 января 2012
encode("utf8"

Perl будет использовать стандартные функции ввода-вывода библиотеки C для открытия файлов, и в Windows, где имена файлов изначально Unicode (UTF-16 за кулисами), это означает, что библиотека должна интерпретировать имя файла в этом байтовом интерфейсе как в определенной кодировке.

Вот проблема: выбранная кодировка никогда не является UTF-8 или любым другим UTF. Это кодировка по умолчанию для конкретной локали, известная (вводящая в заблуждение) как кодовая страница ANSI. На западной установке Windows это cp-1252. В общем, что вы можете узнать, позвонив по номеру Win32::Codepage::get_encoding.

Таким образом, преобразовав вашу строку в эту кодировку, вы можете получить к ней доступ, используя встроенную поддержку файлов, , пока все символы в пути к файлу находятся на кодовой странице ANSI. Для датчан на западной машине это нормально; для датского на китайском компьютере или наоборот вы всегда получите ошибку «файл не найден».

Так что, если вы хотите поддерживать имена файлов со всеми символами Unicode в Windows, у вас нет другого выбора, кроме как использовать Win32 API вместо этого, как Win32::Unicode::File. Это не уникально для Perl; другие языки без явной поддержки имен файлов Unicode имеют точно такую ​​же проблему.

...