【发布时间】:2024-05-03 04:10:04
【问题描述】:
这是一个没有特殊字符的简单文本文件,名为utf-8.txt,内容如下。
foo bar baz
one two three
新行遵循 unix 约定(一个字节),因此文件的整个大小为 26 = 11 + 1 + 13 + 1。(11 = foo bar baz, 13 = one two three。
如果我使用以下 perl 脚本读取文件
use warnings;
use strict;
open (my $f, '<', 'utf8.txt');
<$f>;
seek($f, -4, 1);
my $xyz = <$f>;
print "$xyz<";
打印出来
baz
<
这是意料之中的,因为seek 命令返回四个字符,新行和三个属于baz。
如果我现在将open 语句更改为
open (my $f, '<:encoding(UTF-8)', 'utf8.txt');
输出变为
baz
<
也就是说,seek 命令返回五个字符(或者它返回四个字符但跳过新行)。
这是预期的行为吗?是否有标志或其他东西可以关闭此行为?
编辑
根据 Andrzej A. Filip 的建议,当我在 open 语句之后添加 print join("+",PerlIO::get_layers($f)),"\n"; 时,它会在“正常”打开的情况下打印:unix+crlf 和 @987654336 @案例:unix+crlf+encoding(utf-8-strict)+utf8.
【问题讨论】:
-
在两个脚本中的
open之后添加以下测试:print join("+",PerlIO::get_layers($f)),"\n"; -
请看我修改后的问题
-
与:crlf层有关。解决方法:
open (my $f, '<', 'utf8.txt'); binmode($f); binmode($f, ':encoding(UTF-8)'); -
(禁用 :crlf 层,但您表示不需要它。)
-
在尝试重现某人的输出时,拥有正确的输入文件会有所帮助。 (重现问题我没有问题。)