在Windows

时间:2015-08-14 15:48:11

标签: perl unicode newline utf-16 byte-order-mark

我需要在 Windows 7框中生成一些带有CRLF行分隔符的UTF-16LE编码文件。 (目前有草莓5.20.1)

我需要在获得正确的输出之前弄乱很长时间,我想知道我的解决方案是否是正确的方法,因为它似乎在Perl的其他语言方面过于复杂。特别是:

  • 为什么Perl使用encoding(UTF-16)生成具有正确BOM的有效UTF-16大端,而如果我使用UTF-16LEUTF-16BE而不使用其他软件包,则没有BOM {1}}?
  • 为什么开箱即用的File::BOM处理似乎有些错误(输出为CRLF而不是0D 0A 00)而没有过滤掉一些错误?我怀疑这对于拥有这么多用户的语言来说可能是一个真正的错误......

以下是我对评论的尝试,我发现正确的是最后的陈述

0D 00 0A 00

1 个答案:

答案 0 :(得分:7)

  

手动BOM,但CRLF确定

是的,以下内容确实是正确的:

:raw:encoding(UTF-16LE):crlf + manual BOM
  • :raw“清除”现有的:crlf:encoding图层。
  • :encoding在字节和代码点之间进行转换。
  • :crlf在CRLF和LF之间进行转换。

所以,

                               Read
        ===================================================>

                               Code                 Code
+------+   bytes   +------+   Points   +-------+   Points   +------+
| File |-----------| :enc |------------| :crlf |------------| Code |
+------+           +------+    CRLF    +-------+     LF     +------+ 

        <===================================================
                               Write

您希望对代码点(而不是字节)执行CRLF⇔LF转换,就像使用此设置一样。

  

正确的方式? :自动BOM,CRLF正常

虽然:raw:encoding(UTF-16LE):crlf:via(File::BOM)可能适用于写句柄,但它看起来不正确(我原本期望:raw:via(File::BOM,UTF-16LE):crlf),并且它对于读取句柄来说很糟糕(至少对我来说是Perl 5.16) 0.3)。

我只是看了,:via(File::BOM)背后的代码做了一些非常值得怀疑的事情。我不会用它。

  

为什么Perl使用正确的BOM编码(UTF-16)生成有效的UTF-16大端,而如果我使用UTF-16LE或UTF-16BE而不使用其他包文件则没有BOM :: BOM

因为您可能不需要BOM。

  

为什么开箱即用的CRLF处理似乎有些错误

添加图层会在列表末尾添加它们。如果要在其他位置添加图层(如此处所示),则需要重建列表。

在Perl的开发列表中建议应该区分字节层(例如:unix)和文本层(例如:crlf),以及添加字节或编码层应该挖掘并放置在适当的位置。但是还没有人对此采取行动。

除了简化代码之外,它还允许将UTF-16 * [1] 编码图层添加到STDIN / STDOUT / {{1} (或其他现有句柄)。我相信目前还不可能。

  1. 从技术上讲,CR!= 13或LF!= 10的任何编码都存在此问题,因此EBCDIC也会受到影响。