iconv 生成带 BOM 的 UTF-16

iconv 生成带 BOM 的 UTF-16

灵感来自这个问题,我可以使用该iconv命令生成带有 BOM 和指定字节顺序的 UTF-16 输出吗?

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

例如:

echo hello | iconv -f ascii -t utf-16

生成 的 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//

此命令:

echo hello | iconv -f ascii -t utf-16be

生成大端 UTF-16无物料清单;它似乎假设如果您指定了字节序,则无需在输出中指明它。同样,utf-16le生成没有 BOM 的小端 UTF-16。

这:

echo hello | iconv -f ascii -t utf-16

在我的 x86 Ubuntu 系统上生成 little-endian UTF-16BOM——但我已经看到过一份报告称,即使在小端系统上,类似的命令也会生成带有 BOM 的大端 UTF-16。

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

另一种解决方法,如果您知道字节序-t utf-16会产生什么吗?是:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null

我想喜欢使用方法是这样的:

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM

iconv不支持这一点。

编辑 :

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

echo hello | iconv -f ascii -t utf-16 | od -x

答案1

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

这是来自Unicode 联盟

问:我应该如何处理 BOM?

答:请遵循以下指导原则:

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

(我强调)

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


更新。

题外话

在我看来:

  1. 指定 BOM 的选项对于 iconv 来说无疑是一个有用的附加功能。

  2. 无 BOM 的 UTF-16LE 文件适用于 Windows,但有时需要付出更多努力。例如,记事本的“文件打开”对话框允许您选择“Unicode”,这是 Microsoft 为“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 输出吗?“ 目前 ”“。

答案2

如果要将 BOM 添加到文件,您可以手动添加:

对于 UTF-8 BOM(EF BB BF)

file='main.cpp'
printf '\xEF\xBB\xBF' > $file.utf8
iconv -f ASCII -t UTF-8 $file >> $file.utf8
mv -v $file.utf8 "converted-$file"

对于 UTF-16BE BOM(FE FF)

file='main.cpp'
printf '\xFE\xFF' > $file.utf16be
iconv -f ASCII -t UTF-16BE $file >> $file.utf16be
mv -v $file.utf16be "converted-$file"

对于 UTF-16LE BOM(FF FE)

file='main.cpp'
printf '\xFF\xFE' > $file.utf16le
iconv -f ASCII -t UTF-16LE $file >> $file.utf16le
mv -v $file.utf16le "converted-$file"

笔记:

您可能注意到每种情况下的 BOM 都不同。您可以找到更多信息请点击此处

相关内容