我正在寻找有关如何使用Unicode字符创建文件名的一些指导原则。考虑:
use open qw( :std :utf8 );
use strict;
use utf8;
use warnings;
use Data::Dump;
use Encode qw(encode);
my $utf8_file_name1 = encode('UTF-8', 'æ1', Encode::FB_CROAK | Encode::LEAVE_SRC);
my $utf8_file_name2 = 'æ2';
dd $utf8_file_name1;
dd $utf8_file_name2;
qx{touch $utf8_file_name1};
qx{touch $utf8_file_name2};
print (qx{ls æ*});
输出结果为:
"\xC3\xA61"
"\xE62"
æ1
æ2
为什么我用UTF8编码文件名不重要? (无论哪种方式,文件名仍然是有效的UTF8。)
答案 0 :(得分:5)
因为一个名为" Unicode Bug"的错误。发生了以下情况:
use Encode qw( encode_utf8 is_utf8 );
my $bytes = is_utf8($str) ? encode_utf8($str) : $str;
is_utf8
检查标量使用的两种字符串存储格式中的哪一种。除了Unicode Bug之外,这是一个你永远不必担心的内部实现细节。
您的程序有效,因为encode
总是返回is_utf8
返回false的字符串,use utf8;
总是返回一个字符串,如果字符串包含非is_utf8
,则返回true -ASCII字符。
如果你没有encode
,你有时会得到错误的结果。例如,如果您使用"\x{E6}2"
而不是'æ2'
,即使字符串具有相同的长度和相同的字符,您也会获得不同的文件名。
$ dir
total 0
$ perl -wE'
use utf8;
$fu="æ";
$fd="\x{E6}";
say sprintf "%vX", $_ for $fu, $fd;
say $fu eq $fd ? "eq" : "ne";
system("touch", $_) for "u".$fu, "d".$fd
'
E6
E6
eq
$ dir
total 0
-rw------- 1 ikegami ikegami 0 Jul 12 12:18 uæ
-rw------- 1 ikegami ikegami 0 Jul 12 12:18 d?