我正在尝试修复的特殊问题涉及使用存储在本地驱动器上的图像文件,以及操作可能包含外来字符的文件名.下面显示的两个实验是中间调试步骤.
ã字符在拉丁语中很常见.例如http://pt.wikipedia.org/wiki/Cão
实验1
仔细看,请注意cão如何成为cao.
实验2
在这里我尝试使用File :: Find而不是管道输入,以防问题出现在Windows的Windows实现中shell运算符.这个问题实际上变得更糟,因为~a变成Pi:
调试更新:
我尝试了http://perldoc.perl.org/perlunicode.html列出的一些技巧,
例如使用utf8,使用功能’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
解决方法
在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输出到控制台仍然有更多的陷阱.