使用unicode字符创建文件名

Håk*_*and 5 unicode perl utf-8

我正在寻找一些如何使用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 æ*});
Run Code Online (Sandbox Code Playgroud)

输出是:

"\xC3\xA61"
"\xE62"
æ1
æ2
Run Code Online (Sandbox Code Playgroud)

如果我用UTF8编码文件名,为什么不重要?(无论哪种方式,文件名仍然是有效的UTF8.)

ike*_*ami 5

因为一个名为"Unicode Bug"的错误.发生了以下情况:

use Encode qw( encode_utf8 is_utf8 );

my $bytes = is_utf8($str) ? encode_utf8($str) : $str;
Run Code Online (Sandbox Code Playgroud)

is_utf8检查标量使用两种字符串存储格式中的哪一种.除了Unicode Bug之外,这是一个您永远不必担心的内部实现细节.

您的程序有效,因为encode始终返回一个is_utf8返回false use utf8;的字符串,并且is_utf8如果该字符串包含非ASCII字符,则始终返回一个返回true的字符串.

如果你不这样做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?
Run Code Online (Sandbox Code Playgroud)