Perl:管理 Windows 上的路径编码

发布于 2024-10-03 03:33:17 字数 405 浏览 1 评论 0原文

我正在努力处理包含非英文字符的路径(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.";

I am struggling working with a path containing non English characters (Activestate Perl, Windows XP). How do I open, write, copy, etc. a file located in a path with let say Greek/Russian/French accented characters? Let's say the directory I want to copy my text.txt file to is: 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.";

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烟酉 2024-10-10 03:33:17

我没有特权投票赞成 Chris Dolan 的答案,但我已经使用基于 Win32::Codepage

这可能需要确认,但我认为 Perl 假定所有非 ASCII 路径名都使用 UTF8。在 Linux 和 OS X 上,这可以正常工作,因为操作系统路径名以 UTF8 编码。但是,在旧版本的 Windows 上(Windows 7 之前的版本?),路径名以所在国家/地区的区域设置进行编码(例如,日本的 Shift-jis)。因此,所有返回带有非 ASCII 字符的路径名的 Perl 调用都会变得混乱。

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

I don't have privileges to vote up the answer from Chris Dolan but I have resolved this problem for path names here in Japan with the same solution based on Win32::Codepage.

This probably needs confirmation but I think Perl assumes UTF8 for all non-ASCII path names. On Linux and OS X, this works fine because the OS pathnames are encoded in UTF8. But, on older versions of Windows (pre Windows 7?) pathnames are encoded in the locale of the country (e.g. Shift-jis here in Japan). So, all Perl calls that return pathnames with non-ASCII characters get messed up.

The solution that I used was to find the locale encoding using Win32:Codepage and then encode that to UTF8 when reading files. Then, when writing (or updating) files, I would decode back to the locale encoding.

酒浓于脸红 2024-10-10 03:33:17

几年前,我在一个项目中遇到了同样的问题(我们的 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)'

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

I had this same problem in a project a few years back (our PAR-packed GUI app had to work under Shift-JIS encoding). I tried LOTS of techniques to make Perl 5.8 do this right automatically. In the end, my tedious-but-effective solution was to encode EVERY filename just before passing it to the builtins.

First, set up the utility function:

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;
}

Then, use it everywhere:

next if (! -d encode_filename($tmpldir));
my $file = SWF::File->new(encode_filename($dest));
@entries = File::Slurp::read_dir(encode_filename($srcdir));
etc...

I even wrote a little checker to make sure I used it everywhere!

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

If you miss even one, you'll get the "Wide-character" warning at runtime...

动次打次papapa 2024-10-10 03:33:17

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

Perl's native functions cannot be used in this case. Use functions in Win32 module which support Unicode characters. Win32 was first released with perl v5.8.7.

心凉 2024-10-10 03:33:17

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

I discovered I had to disable UAC (User Access Control) on Microsoft Windows Vista before I could successfully install either Win32::Locale or Win32::Codepage. (Thank you, Chris Dolan, for writing the latter module.)

独孤求败 2024-10-10 03:33:17

我在 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 => "/" }
                                    );

这对我的安装有帮助。

I also had problems with UAC (User Access Control) on Windows 7 and newer.
I finally found out, that access to the required Registry key only has read permissions since WIndows Vista.
You can easily patch Win32::Codepage to work without administrative privileges if you open the file in your favourite editor and replace:

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

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

This has helped on my installation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文