Perl:在Windows上pipe理path编码

我正在努力使用包含非英文字符(Activestate Perl,Windows XP)的path。 如何打开,写入,复制位于path中的文件,并说出希腊语/俄语/法语重音字符? 假设我想将我的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."; 

Solutions Collecting From Web of "Perl:在Windows上pipe理path编码"

几年前,我在一个项目中遇到了同样的问题(我们的PAR包装的GUI应用程序必须在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)' 

如果你甚至错过了,你会在运行时得到“宽字符”的警告。

我没有权利投票从克里斯Dolan的答案,但我已经解决了这个问题在日本的路径名称与基于Win32 :: Codepage相同的解决方案。

这可能需要确认,但我认为Perl会为所有非ASCII路径名称使用UTF8。 在Linux和OS X上,这个工作正常,因为操作系统的路径名是用UTF8编码的。 但是,在较早版本的Windows(Windows 7以前版本)中,路径名在国家/地区编码(例如,日本的Shift-jis)。 所以,所有返回非ASCII字符路径名的Perl调用都会搞砸。

我使用的解决方案是使用Win32:Codepage查找语言环境编码,然后在读取文件时将其编码为UTF8。 然后,在写入(或更新)文件时,我将解码回到区域设置编码。

Perl的本地函数不能在这种情况下使用。 使用支持Unicode字符的Win32模块中的函数。 Win32首先在perl v5.8.7上发布。

我发现我必须在Microsoft Windows Vista上禁用UAC( 用户访问控制 ),才能成功安装Win32::LocaleWin32::Codepage 。 (谢谢Chris Dolan写下后一个模块。)

我在Windows 7和更新的UAC(用户访问控制)方面也遇到了问题。 我终于发现,自从Windows Vista以来,对所需注册表项的访问只具有读权限。 如果你打开你最喜欢的编辑器中的文件,你可以很容易地修补Win32 :: Codepage的工作没有管理权限,并取代:

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

这有助于我的安装。