我有一些perl代码,可以使用File :: Path :: rmtree函数删除文件夹。如果文件夹结构包含ascii字符文件/文件夹,则此函数成功运行,但如果文件夹包含Unicode字符文件/文件夹,则该函数失败。.我正在使用的Perl版本是“这是perl 5、12版,subversion 4(v5.12.4)构建的用于MSWin32-x86-多线程”
我也尝试使用最新的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”的文件名为“ chinese_trad_我的文件.txt”,则出现错误,因为“无法删除XXX的目录:D:\ tmp \ rmtree中的目录不为空.pm第XX行”。
谢谢!
答案 0 :(得分:2)
文件名始终是字节。不幸的是,没有迹象表明或要求文件名中的Unicode字符以某种编码表示,并且每个OS都有不同的约定。在大多数类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
答案 1 :(得分:2)
您可以使用Win32::Unicode::File和Win32::Unicode::Dir提供的字幕来做您想做的事。
Windows为每个接受或返回文本的API调用提供两个版本。
带有“ A”(ANSI)后缀的版本期望并返回使用系统的“活动代码页”编码的文本。 ("cp".Win32::GetACP()
提供了可与Encode提供的子代码一起使用的编码名称。)
例如,DeleteFileA
系统调用用于删除文件,并且期望使用系统的“活动代码页”对路径进行编码。
后缀“ W”(宽)的版本期望并返回使用UTF-16le编码的文本。
例如,DeleteFileW
系统调用用于删除文件,并且期望使用UTF-16le编码的路径。
Perl使用所有系统调用的“ A”版本。这里需要“ W”版本。
上面提到的模块提供对所需呼叫的“ W”版本的访问。