iconv使用BOM生成UTF-16


11

这个问题的启发,我可以使用该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

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

这个:

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

生成(在我的x86 Ubuntu系统上)带有 BOM的小尾数UTF-16 -但是我已经看到了类似的命令的报告,即使在小尾数系统上也生成带有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
BOM会降低数据的可移植性,但您可以通过这种方式添加它
RedGrittyBrick 2012年

@RedGrittyBrick:它如何降低可移植性(特别是对于UtF-16)?我知道我可以轻松生成BOM。我正在寻找一种仅使用iconv- 的方式,并想知道为什么-t utf-16似乎没有保留字节序。
基思·汤普森

我猜iconv假设当前平台字节序,如果您未明确指定的话。在Windows以外的某些平台上,某些文本处理工具不希望使用BOM,因此会做错事情。例如,串联文本文件或使用基于文件的模板来构造内容时。“对于IANA注册的字符集UTF-16BE和UTF-16LE,不应该使用字节顺序标记,因为这些字符集的名称已经确定了字节顺序”
RedGrittyBrick 2012年

这个问题表明iconv -f UTF-8 -t UTF-16,它在低端系统(MacOS)上运行,生成带有BOM的大端UTF-16,这似乎很奇怪。
Keith Thompson

Answers:


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大端或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输出 ”的答案当前为“ ”。


1
那么第一条准则A.1呢?如果我想生成在x86 Windows系统上可用的Unicode文本文件,则它应该是带有BOM的低端UTF16文件。
基思·汤普森

@KeithThompson:系统应接受 utf16le应按和utf16be应按。.txt只要文件包含BOM表,至少在Windows记事本中都接受-。
user1686

@KeithThompson:我同意准则1应该优先,但是iconv不能为您提供指定BOM的方法。您最初的问题的答案就是“否”。
RedGrittyBrick 2012年

不是我希望的答案,而是一个答案,还有一个彻底的答案!
Keith Thompson

2
这个答案对我有所帮助-帮助我了解了为什么被搞砸了。标准的Windows程序从注册表,以出口/进口,C:\Windows\System32\reg.exe出口UTF-16 LE带BOM和将只读UTF-16 LE与BOM -将无法读取UTF-16 LE 没有 BOM,并不会阅读UTF-16 与BOM -换句话说,它在读取时需要BOM,但最好还是选择合适的BOM (幸运的是,它读取的是UTF-8。)
davidbak
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.