:编码使用:编码(ENCODING)在open()或binmode()中 安装一个透明地进行字符集和编码的层 转换,例如从Shift-JIS到Unicode。注意 在stdio下:编码也启用:utf8。请参阅PerlIO :: encoding for 更多信息。
这是一个测试脚本:
use feature qw(say);
use strict;
use warnings;
my $fn = 'test.txt';
for my $mode ('>', '>:encoding(utf8)' ) {
open( my $fh, $mode, $fn);
say join ' ', (PerlIO::get_layers($fh));
close $fh;
}
输出是:
unix perlio
unix perlio encoding(utf8) utf8
为什么我在这里获得额外的utf8
图层?
答案 0 :(得分:8)
由于需要了解Perl内部的原因。
当您将数字4
存储在标量中时,它可以存储为有符号整数,无符号整数或浮点数。您不知道使用了哪个,并且您没有任何理由关心使用哪个。 Perl会根据需要自动转换。
字符串也是如此。它们有两种存储格式。你的名字就是一个很好的例子。 “HåkonHægland”可以存储为
48.E5.6B.6F.6E.20.48.E6.67.6C.61.6E.64
或
48.C3.A5.6B.6F.6E.20.48.C3.A6.67.6C.61.6E.64
名为UTF8
的标志表示存储格式的选择。这对用户来说是透明的(或者至少应该是这样)。
$ perl -Mutf8 -E'
$_ = "Håkon Hægland";
utf8::downgrade( $d = $_ ); # Converts to the first format mentioned above.
utf8::upgrade( $u = $_ ); # Converts to the second format mentioned above.
say $d eq $u ? "eq" : "ne";
'
eq
虽然它对你来说是透明的,但它对Perl本身来说远非透明。每当你操作一个字符串时,Perl必须检查它存储的存储格式。例如,如果你连接两个字符串,Perl必须确保它们在执行连接之前使用相同的存储格式,必要时转换一个。
PerlIO也不透明。与Perl的其余部分一样,PerlIO必须处理字符串缓冲区中的字节,而不是您在Perl级别上看到的字节。有时,这些字节注定是标量的字符串缓冲区,其中UTF8
标志被清除,有时,这些字节注定是设置了UTF8
标志的标量的字符串缓冲区。 PerlIO需要跟踪它。当通过读取句柄获得的标量需要设置:utf8
标志时,PerlIO不会在层与层之间携带标记,而是添加UTF8
层。
因此,:encoding
转换形成
Håkon Hægland
从指定的编码到
48.C3.A5.6B.6F.6E.20.48.C3.A6.67.6C.61.6E.64
:utf8
导致标量设置UTF8
标志,导致生成的标量包含
U+0048.00E5.006B.006F.006E.0020.0048.00E6.0067.006C.0061.006E.0064