【问题标题】:Perl: Open output file in same endianess as input file – UTF-16be vs. UTF-16lePerl:以与输入文件相同的字节顺序打开输出文件 – UTF-16be 到。 UTF-16 文件
【发布时间】:2015-03-04 14:30:42
【问题描述】:

当 Perl 打开一个 UTF-16 编码的文件时,

open my $in, "< :encoding(UTF-16)", "text-utf16le.txt" or die "Error $!\n";

它会自动检测endianess 感谢Byte Order Mark

但是当我打开文件进行写入时

open my $out, "> :encoding(UTF-16)", "output.txt" or die "Error $!\n";

Perl 默认以大端方式打开它。

请问如何指定以与输入文件相同的字节序打开输出文件?

如何从输入文件句柄$in 中获取字节序/编码? PerlIO::get_layers($in) 在其他层中返回 encoding(UTF-16)

【问题讨论】:

    标签: perl encoding endianness utf-16


    【解决方案1】:

    您必须自己阅读 BOM。

    use IO::Unread qw( unread );
    
    open(my $fh_in, "<:raw", $qfn)
       or die;
    
    my $rv = read($fh_in, my $buf, 4);
    defined($rv)
       or die;
    
    my $encoding;
    my $bom_present;
    if    ($buf =~ s/^\x00\x00\xFE\xFF//) { $encoding = 'UTF-32be'; $bom_present = 1; }
    elsif ($buf =~ s/^\xFF\xFE\x00\x00//) { $encoding = 'UTF-32le'; $bom_present = 1; }
    elsif ($buf =~ s/^\xFE\xFF//        ) { $encoding = 'UTF-16be'; $bom_present = 1; }
    elsif ($buf =~ s/^\xFF\xFE//        ) { $encoding = 'UTF-16le'; $bom_present = 1; }
    elsif ($buf =~ s/^\xEF\xBB\xBF//    ) { $encoding = 'UTF-8';    $bom_present = 1; }
    else {
       $encoding = 'UTF-8';
       $bom_present = 0;
    }
    
    unread($fh_in, $buf) if length($buf);
    
    binmode($fh_in, ":encoding($encoding)");
    binmode($fh_in, ":crlf") if $^O eq 'MSWin32';
    

    但有人已经为你做到了:

    use File::BOM qw( open_bom );
    
    my $encoding = open_bom(my $fh_in, $qfn, ':encoding(UTF-8)');
    

    【讨论】:

      猜你喜欢
      • 2012-02-23
      • 2015-02-19
      • 2011-11-17
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      相关资源
      最近更新 更多