为什么Perl会在Windows上丢失外来字符; 这可以修复(如果是这样,如何)?

Ale*_*x R 5 unicode perl windows-7

请注意以下如何ã更改a.注意2:在将此错误归咎于CMD.EXE和Windows管道怪异之前,请参阅下面的实验2,它使用File :: Find获得类似的问题.

我正在尝试修复的特殊问题涉及使用存储在本地驱动器上的图像文件,以及操作可能包含外来字符的文件名.下面显示的两个实验是中间调试步骤.

这个ã角色在拉丁语中很常见.例如http://pt.wikipedia.org/wiki/Cão

实验1

仔细一看,注意如何cãocao. 替代文字

实验2

在这里我尝试使用File :: Find而不是管道输入,以防问题出现在|shell运算符的Windows实现中.问题实际上变得更糟,因为~a变成Pi: 替代文字


调试更新:

我尝试了一些在列出的招数http://perldoc.perl.org/perlunicode.html,例如use utf8,use feature 'unicode_strings'等等,都无济于事.


环境和版本信息

操作系统是Windows 7,64位.

Perl是:

This is perl 5, version 12, subversion 2 (v5.12.2) built for MSWin32-x64-multi-thread
(with 8 registered patches, see perl -V for more detail)

Copyright 1987-2010, Larry Wall

Binary build 1202 [293621] provided by ActiveState http://www.ActiveState.com
Built Sep  6 2010 22:53:42
Run Code Online (Sandbox Code Playgroud)

bob*_*nce 6

与许多其他脚本语言一样,Perl构建在C运行时上.

在Windows上,窄(字节)字符的标准MS C运行时使用默认为Windows系统编码('ANSI代码页')的编码,用于IO活动,如打开文件或写入控制台.

ANSI代码页始终是特定于语言环境的编码:通常是单字节,但在某些语言环境中是多字节的(例如中国,日本等).它永远不是UTF-8或其他能够再现整个Unicode的东西; Perl IO可以处理的字符取决于Windows语言环境("非Unicode程序的语言"设置).

虽然可以使用该chcp 65001命令为控制台应用程序提供UTF-8 ,但是在执行此操作时会出现许多严重的不一致.这给Windows上的很多工具带来了困难,这是微软真正需要解决的问题,但到目前为止他们的态度是Unicode等于UTF-16; 每个想要使用Unicode的人都必须使用widechar接口.

因此,您目前无法在Windows上的Perl中可靠地处理使用非ASCII文件名的文件.抱歉.

您可以尝试使用Python(其中添加了特殊的Windows文件名处理以在2.3版本以后解决此问题;请参阅PEP 277)或其中一种支持Unicode的Windows Scripting Host语言.无论哪种方式,在Windows上将Unicode输出到控制台仍然有更多的陷阱.