Как удалить папку с именами символов Unicode, используя Perl rmtree? - PullRequest
1 голос
/ 10 апреля 2019

У меня есть некоторый perl-код, который удаляет папки, используя функцию File :: Path :: rmtree.Эта функция работает успешно, если структура папок содержит файлы / папки символов ascii, но не работает, если папка содержит файлы / папки символов Unicode. Я использую версию Perl: «Это Perl 5, версия 12, subversion 4 (v5.12.4)».для MSWin32-x86-multi-thread "

Я также пытался использовать последнюю версию Perl., но проблема остается.Вот пример кода:

use strict 'vars';
require File::Path;

sub Rmdir($)
{
   my ($Arena) = "D:\\tmp\\TestUnicodeRm";

   if (-d $Arena){
   print "Dir to Rmtree $Arena\n";
       File::Path::rmtree($Arena,0,0);
}

     if (-d $Arena){
        print "Failed to clean up test area $Arena.\n";
     }
}

Rmdir $0;

1;

Если в каталоге 'D: \ tmp \ TestUnicodeRm' есть файл с именем say 'chinese_trad_ 我 的 文件 .txt', то я получаю сообщение об ошибке, поскольку "не удается удалить каталог для XXX: Директория не пуста в строке D: \ tmp \ rmtree.pm XX ".

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 11 апреля 2019

Вы можете использовать подпрограммы, предоставленные Win32 :: Unicode :: File и Win32 :: Unicode :: Dir , чтобы делать то, что вы хотите.


Windows предоставляет две версии каждого вызова API, который принимает или возвращает текст.

  • Версии с суффиксом «A» (ANSI) ожидают и возвращают текст, закодированный с использованием активной кодовой страницы системы.,("cp".Win32::GetACP() предоставляет имя кодировки, которое вы можете использовать с подпрограммами, предоставленными Encode.)

    Например, системный вызов DeleteFileA используется для удаления файла, и он ожидает путь, закодированный с использованием системногоActive Code Page.

  • Версии с суффиксом "W" (Wide) ожидают и возвращают текст, закодированный с использованием UTF-16le.

    Например, DeleteFileWсистемный вызов используется для удаления файла, и он ожидает путь, закодированный с использованием UTF-16le.

Perl использует версию "A" всех системных вызовов.Здесь требуется версия "W".

Упомянутые выше модули обеспечивают доступ к необходимой вам версии вызовов "W".

2 голосов
/ 10 апреля 2019

Имена файлов всегда байты. К сожалению, нет никаких указаний или требований для символов юникода в именах файлов, которые должны быть представлены в определенной кодировке, и каждая ОС имеет различные соглашения. В большинстве Unix-подобных систем имена файлов кодируются в UTF-8 и взаимодействуют с байтами. Однако в Windows имена файлов хранятся как UTF-16, но взаимодействуют как декодированные символы. Звучит как ошибка в File :: Path, что он неправильно обрабатывает эти имена файлов, так как находит их - поскольку вы не предоставляете имена файлов, это не может быть ошибкой в ​​вашем коде.

Я бы сначала предложил убедиться, что у вас File :: Path последней версии (2.16). Если это не сработает, все, что я могу предложить, это сообщить об ошибке и либо вручную рекурсивно использовать opendir и readdir для удаления файлов и подкаталогов, либо выложить в rd /s.

my $rc = system 'rd', '/s', $dir; # check for errors as in system() docs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...