Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl:在Windows上管理路径编码_Windows_Perl_Encoding - Fatal编程技术网

Perl:在Windows上管理路径编码

Perl:在Windows上管理路径编码,windows,perl,encoding,Windows,Perl,Encoding,我正在努力使用包含非英语字符的路径(Activestate Perl、Windows XP)。如何打开、写入、复制位于带有希腊/俄罗斯/法国口音字符的路径中的文件?假设我要将text.txt文件复制到的目录是:C:\Documents and Settings\στα\Desktop use File::Spec; my $save = File::Spec->canonpath( $mw->chooseDirectory() ); my $file = catfile($save

我正在努力使用包含非英语字符的路径(Activestate Perl、Windows XP)。如何打开、写入、复制位于带有希腊/俄罗斯/法国口音字符的路径中的文件?假设我要将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.";

在这种情况下不能使用Perl的本机函数。使用模块中支持Unicode字符的函数。最初与perl v5.8.7一起发布。

几年前,我在一个项目中遇到了同样的问题(我们的PAR-packing GUI应用程序必须在Shift JIS编码下工作)。我尝试了很多技术,使Perl5.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;
}
然后,在任何地方使用它:

我甚至写了一个小的检查,以确保我用它无处不在

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)'

如果你错过了哪怕一个,你会在运行时收到“宽字符”警告…

我没有特权投票支持Chris Dolan的答案,但我已经用基于的相同解决方案解决了日本路径名的问题

这可能需要确认,但我认为Perl假定所有非ASCII路径名都使用UTF8。在Linux和OS X上,这可以正常工作,因为OS路径名是用UTF8编码的。但是,在旧版本的Windows(Windows 7之前?)上,路径名是按照国家/地区编码的(例如,日本的Shift jis)。因此,所有返回非ASCII字符路径名的Perl调用都会出错


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

我发现我必须在Microsoft Windows Vista上禁用UAC(),才能成功安装
Win32::locale
Win32::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 => "/" }
                                    );

这对我的安装很有帮助。

谢谢您的建议。我将脚本更改为除非(Win32::CopyFile($input,$ansi_path,1)){my$err=$^E;if($err==ERROR_已经存在){warn“目录存在,没有问题”;}否则{die Win32::FormatMessage($^E);}但它对希腊语不起作用!!知道吗?对不起。我目前没有Windows系统可供测试。如果我能测试,我会更新我的答案。艾伦的答案是正确的,但不正确。您可以使用带有宽字符编码的Perl本机函数,但必须在将文件名传递给Perl之前将文件名编码为系统编码。查看我的答案。您的代码段有一个问题:您想要“\\text.txt”而不是“\text.txt”。不过,这可能不是您的最终问题。我需要在脚本的开头添加:${^WIDE\u SYSTEM\u CALLS}=1;你上面的答案有一点不正确。Perl默认采用8位拉丁语-1编码字符串。和Shift JIS一样,Latin-1是ASCII的超集。很抱歉上面的错误。是的,是拉丁语1。但主要的一点是Perl使用UTF8,这会弄乱Windows系统上的路径名。在Perl中(在非拉丁1 Windows系统上)使用一个简单的“open”命令而不去处理Win32::Codepage,我仍然感到惊讶。这与文件路径中的重音字符有什么关系?
  $codekey = Win32::TieRegistry->new($CODEPAGE_REGISTRY_KEY,
                                     { Delimiter => "/" }
                                    );

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