假设我在当前目录中有一个名为æ
的文件(UNICODE:0xE6,UTF8:0xC3 0xA6)。
然后,我想使用File::Find::Rule
找到它:
use feature qw(say);
use open qw( :std :utf8 );
use strict;
use utf8;
use warnings;
use File::Find::Rule;
my $fn = 'æ';
my @files = File::Find::Rule->new->name($fn)->in('.');
say $_ for @files;
输出为空,显然这不起作用。
如果我首先尝试编码文件名:
use Encode;
my $fn = 'æ';
my $fn_utf8 = Encode::encode('UTF-8', $fn, Encode::FB_CROAK | Encode::LEAVE_SRC);
my @files = File::Find::Rule->new->name($fn_utf8)->in('.');
say $_ for @files;
输出结果为:
æ
因此它找到了该文件,但返回的文件名未解码为Perl字符串。要解决这个问题,我可以解码结果,用以下代码替换最后一行:
say Encode::decode('UTF-8', $_, Encode::FB_CROAK) for @files;
问题是编码和解码是否可以/应该由File::Find::Rule
自动完成,所以我可以使用原始程序而不必担心编码和解码?
(例如,File::Find::Rule
可以使用I18N::Langinfo
来确定当前区域设置的代码集是UTF-8
??)
答案 0 :(得分:2)
问题是可能存在编码错误的文件名,包括使用与预期不同的编码编码的文件名。这意味着首先需要的是通过解码编码过程对错误编码的文件名进行往返的方法。我认为Python使用代理对代码点来表示坏字节。
您需要一个pragma来确保向后兼容性。