iconv 使用 BOM 生成 UTF-16

Kei*_*son 11 unicode

受此问题的启发,我可以使用该iconv命令生成带有 BOM 和指定字节序的 UTF-16 输出吗?

iconv命令将文本从一种编码转换为另一种编码。

例如:

echo hello | iconv -f ascii -t utf-16
Run Code Online (Sandbox Code Playgroud)

生成 UTF-16 表示"hello\n"

UTF-16 文件通常(但并非总是)以字节顺序标记 (BOM) 开头,它是 Unicode 字符的 2 字节编码U+FEFF。您可以通过检查前两个字节是FE FF或来确定带有 BOM 的 UTF-16 文件的字节序FF FE

iconv命令有几个用于生成 UTF-16 输出的选项:

$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//
Run Code Online (Sandbox Code Playgroud)

这个命令:

echo hello | iconv -f ascii -t utf-16be
Run Code Online (Sandbox Code Playgroud)

生成没有 BOM 的big-endian UTF-16 ;似乎假设如果您指定了字节顺序,则不需要在输出中指明它。同样,utf-16le生成没有 BOM 的小端 UTF-16。

这个:

echo hello | iconv -f ascii -t utf-16
Run Code Online (Sandbox Code Playgroud)

生成(在我的 x86 Ubuntu 系统上)带有BOM 的little-endian UTF- 16——但我已经看到类似命令的报告生成带有 BOM 的 big-endian UTF-16,即使是在 little-endian 系统上。

我总是可以手动使用utf-16beutf-16le预先添加 BOM,但我正在寻找只使用该iconv命令的解决方案。

另一种解决方法,如果你知道字节序-t utf-16生成的是什么,是:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

我会喜欢到使用是一样的东西:

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM
Run Code Online (Sandbox Code Playgroud)

iconv不支持。

编辑 :

可以访问 x86 Mac OSX 系统的人可以发表评论显示以下命令的(复制和粘贴)输出吗?

echo hello | iconv -f ascii -t utf-16 | od -x
Run Code Online (Sandbox Code Playgroud)

Red*_*ick 9

,如果您指定字节顺序,iconv则不会插入 BOM。

这是来自Unicode 联盟

问:我应该如何处理 BOM?

答:以下是一些需要遵循的准则:

  1. 特定协议(例如 Microsoft 对 .txt 文件的约定)可能需要在某些 Unicode 数据流(例如文件)上使用 BOM。当您需要遵守此类协议时,请使用 BOM。
  2. 某些协议允许在未标记文本的情况下使用可选的 BOM。在这些情况下,
    • 在已知文本数据流是纯文本但编码未知的情况下,可以将 BOM 用作签名。如果没有 BOM,则编码可以是任何内容。
    • 如果已知文本数据流是纯 Unicode 文本(但不知道是哪种字节序),则可以将 BOM 用作签名。如果没有 BOM,则文本应解释为 big-endian。
  3. 一些面向字节的协议要求在文件开头使用 ASCII 字符。如果 UTF-8 与这些协议一起使用,则应避免使用 BOM 作为编码表单签名。
  4. 如果数据流的精确类型已知(例如 Unicode big-endian 或 Unicode little-endian),则不应使用 BOM。特别是, 当数据流被声明为 UTF-16BE、UTF-16LE、UTF-32BE 或 UTF-32LE 时,不得使用BOM 。

(我的重点)

我希望iconv尝试忠实于这些准则中的最后一条。


更新。

题外话

在我看来:

  1. 指定 BOM 的选项肯定是 iconv 的一个有用的附加功能。

  2. 没有BOM的UTF-16LE文件可在Windows,尽管有时额外的努力。例如,记事本的文件打开对话框允许您选择“Unicode”,这是微软对“UTF-16LE”的名称,并且(不出所料)似乎可以处理没有 BOM 的文件。

  3. 我可以在 Windows 记事本 (XP) 中以通常的方式打开 UTF-16LE 测试文件(无 BOM)或 UTF-8 测试文件(无 BOM),例如在资源管理器中双击文件名。这对我来说似乎有用。我知道有时 Windows 会错误地猜测编码 - 在这种情况下,您必须在打开文件时告诉记事本编码。这种不便意味着对于打算在 Windows 上使用的文本文件,最好包含 BOM。

  4. 如果特定应用程序不能使用带有 BOM 的 UTF-16LE 文件以外的任何其他文件,那么我同意没有 BOM 的 UTF-16LE 文件不适用于该特定应用程序。

  5. 我怀疑如果您可以使一切都使用 UTF-8(没有 BOM),那么从长远来看,这是最好的解决方案。

但是,“我可以使用 iconv 命令生成带有 BOM 和指定字节序的 UTF-16 输出吗”这个问题的答案目前是“”。

  • 这个答案帮助了我 - 帮助我了解了为什么我被搞砸了。从注册表导出/导入的标准 Windows 程序,`C:\Windows\System32\reg.exe` 导出 UTF-16 LE WITH BOM 并且将 _only 读取 UTF-16 LE WITH BOM_ - 不会读取 UTF-16 LE _without_ BOM 和 _will not_ 读取 UTF-16 BE _with BOM_ - 换句话说,它在读取时需要 BOM 但_它最好是正确的!_(幸运的是,它读取 UTF-8。) (2认同)