【问题标题】:CRLF translation with Unicode in PerlPerl 中使用 Unicode 的 CRLF 翻译
【发布时间】:2011-03-20 05:02:52
【问题描述】:

我正在尝试在 Windows 上使用 Perl 写入 Unicode(UCS-2 Little Endian)文件,就像这样。

open my $f, ">$fName" or die "can't write $fName\n";
binmode $f, ':raw:encoding(UCS-2LE)';
print $f, "ohai\ni can haz unicodez?\nkthxbye\n";
close $f;

它基本上可以正常工作,只是我不再获得在常规文本文件上获得的输出的自动 LF -> CR/LF 翻译。 (输出文件只有 LF)如果我在“binmode”调用中省略 :raw 或添加 :crlf,那么输出文件就会出现乱码。我尝试重新排序“指令”(即:原始编码之前的:编码)并且无法使其工作。阅读也存在同样的问题。

【问题讨论】:

    标签: perl unicode


    【解决方案1】:

    这适用于我在 Windows 上:

    open my $f, ">:encoding(UCS-2LE):crlf", "test.txt";
    print $f "ohai\ni can haz unicodez?\nkthxbye\n";
    close $f;
    

    在 test.txt 中生成 UCS-16 LE 输出

    ohai
    i can haz unicodez?
    kthxbye
    

    【讨论】:

    • 真的吗?!当我在 Notepad+(支持 Unicode)中打开第二行时,第二行看起来像亚洲字符。当我在 HexEdit 中打开它时,我可以明白为什么...这些行以 \x00 \x0D \x0A 结尾(而不是 \x00 \x0D \x00 \x0A),这使得第二行“不同步”
    • 我看到以 \x00 \x0D \x00 \x0A 结尾的行。或者正如 hexlify-buffer 所说,0d00 0a00。你用的是什么版本的perl?我正在使用最新的草莓发行版。
    • 哇,这很奇怪...我也在使用最新的 Strawberry Perl (5.12),我只是再次尝试以确保...我仍然看到 00 0D 0A...也许您使用的是 5.10,这是 5.12 中引入的错误?
    • This is perl 5, version 12, subversion 0 (v5.12.0) built for MSWin32-x86-multi-thread,并不是说这对我们有多大帮助。我想知道我是否安装了某种影响编码和 crlf 的模块。当我可以访问并发布结果时,我会在另一台或两台计算机上尝试。
    • 也许操作系统很重要?我在 Windows 7 64 位上(虽然我使用的 MSWin32-x86-multi-thread 和你一样)
    【解决方案2】:

    :crlf 层在输出流中执行 0x0A -> 0x0D 0x0A (\n --> \r\n) 的简单字节映射,但在大多数情况下,这在任何宽字符编码中都无效。

    使用原始模式但显式打印 CR 怎么样?

    print $f "ohai\r\ni can haz unicodez?\r\nkthxbye\r\n";
    

    或者如果考虑到可移植性,发现并明确使用正确的行尾:

    ## never mind - $/ doesn't work
    # print $f "ohai$/i can haz unicodez?$/kthxbye$/";
    
    open DUMMY, '>', 'dummy'; print DUMMY "\n"; close DUMMY;
    open DUMMY, '<:raw', 'dummy'; $EOL = <DUMMY>; close DUMMY;
    unlink 'dummy';
    
    ...
    
    print $f "ohai${EOL}i can haz unicodez?${EOL}kthxbye${EOL}";
    

    【讨论】:

    • 没有办法让 :crlf 层在 :encoding 层之前工作?
    • 据我所知没有。也许其他人有一个想法。
    【解决方案3】:

    这是我发现的工作,至少对于 perl 5.10.1:

    输入:

    open(my $f_in, '<:raw:perlio:via(File::BOM):crlf', $file);
    

    输出:

    open(my $f_out, '>:raw:perlio:encoding(UTF-16LE):crlf:via(File::BOM)', $file);
    

    它们透明地处理 BOM、CRLF 翻译和 UTF-16LE 编码/解码。

    请注意,根据下面的 perlmonks 帖子,如果尝试使用 binmode() 而不是 open() 指定,则需要额外的 ":pop":

    binmode $f_out, ':raw:pop:perlio:encoding(UTF-16LE):crlf';
    

    我的经验证实了这一点。但是,我无法让它与 ":via(File::BOM)" 层一起使用。

    参考资料:

    http://www.perlmonks.org/?node_id=608532

    http://metacpan.org/pod/File::BOM

    【讨论】:

      猜你喜欢
      • 2013-07-24
      • 1970-01-01
      • 2011-10-20
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 2014-10-12
      • 2014-02-27
      相关资源
      最近更新 更多