如何使用Perl rmtree删除带有unicode字符文件名的文件夹?

问题描述 投票:1回答:2

我有一些perl代码使用函数File :: Path :: rmtree删除文件夹。如果文件夹结构包含ascii字符文件/文件夹,则此函数成功运行,但如果文件夹包含Unicode字符文件/文件夹则失败。我使用的Perl版本是“这是perl 5,版本12,颠覆4(v5.12.4)构建的for 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'的文件名称为'chinese_trad_我的文件.txt',则会收到错误消息“无法删除XXX的目录:D:\ tmp \ rmtree.pm行中的目录不为空XX”。

提前致谢!

perl unicode
2个回答
2
投票

你可以使用Win32::Unicode::FileWin32::Unicode::Dir提供的潜艇来做你想做的事。


Windows提供了接受或返回文本的每个API调用的两个版本。

  • 具有“A”(ANSI)后缀的版本期望并返回使用系统的活动代码页编码的文本。 ("cp".Win32::GetACP()提供了一个编码名称,您可以使用Encode提供的子代码。) 例如,DeleteFileA系统调用用于删除文件,它需要使用系统的活动代码页编码的路径。
  • 具有“W”(宽)后缀的版本期望并返回使用UTF-16le编码的文本。 例如,DeleteFileW系统调用用于删除文件,它需要使用UTF-16le编码的路径。

Perl使用所有系统调用的“A”版本。这里需要“W”版本。

上面提到的模块可以访问您需要的“W”版本的呼叫。


2
投票

文件名总是字节。遗憾的是,没有迹象或要求文件名中的unicode字符以特定编码表示,并且每个OS具有不同的约定。在大多数类Unix系统中,文件名被编码为UTF-8并与字节进行交互。但是在Windows中,文件名存储为UTF-16,但与解码后的字符进行交互。这听起来像File :: Path中的一个错误,因为它没有正确处理这些文件名,因为它们没有提供文件名,它不能成为代码中的错误。

我首先建议确保你的File :: Path是最新版本(2.16)。如果这不起作用,我可以建议报告一个错误,并手动递归使用opendir和readdir来删除文件和子目录,或者shell到rd /s

my $rc = system 'rd', '/s', $dir; # check for errors as in system() docs
© www.soinside.com 2019 - 2024. All rights reserved.