使用iconv将UTF8转换为UTF16

Per*_*com 26 linux unicode macos command-line

当我使用iconv从UTF16转换为UTF8时,一切都很好,反之亦然,它不起作用.我有这些文件:

a-16.strings:    Little-endian UTF-16 Unicode c program text
a-8.strings:     UTF-8 Unicode c program text, with very long lines
Run Code Online (Sandbox Code Playgroud)

编辑器中的文本看起来没问题.当我运行这个:

iconv -f UTF-8 -t UTF-16LE a-8.strings > b-16.strings
Run Code Online (Sandbox Code Playgroud)

然后我得到这个结果:

b-16.strings:    data
a-16.strings:    Little-endian UTF-16 Unicode c program text
a-8.strings:     UTF-8 Unicode c program text, with very long lines
Run Code Online (Sandbox Code Playgroud)

file实用程序不显示预期的文件格式,并且文本在编辑器中也不好看.可能是iconv无法创建正确的BOM吗?我在MAC命令行上运行它.

为什么b-16不是正确的UTF-16LE格式?还有另一种方法将utf8转换为utf16吗?

下面将详细阐述.

$ iconv -f UTF-8 -t UTF-16LE a-8.strings > b-16le-BAD-fromUTF8.strings
$ iconv -f UTF-8 -t UTF-16 a-8.strings > b-16be.strings 
$ iconv -f UTF-16 -t UTF-16LE b-16be.strings > b-16le-BAD-fromUTF16BE.strings

$ file *s
a-16.strings:                   Little-endian UTF-16 Unicode c program text, with very long lines
a-8.strings:                    UTF-8 Unicode c program text, with very long lines
b-16be.strings:                 Big-endian UTF-16 Unicode c program text, with very long lines
b-16le-BAD-fromUTF16BE.strings: data
b-16le-BAD-fromUTF8.strings:    data


$ od -c a-16.strings | head
0000000  377 376   /  \0   *  \0      \0  \f 001   E  \0   S  \0   K  \0

$ od -c a-8.strings | head 
0000000    /   *   *   *       ?  **   E   S   K   Y       (   J   V   O

$ od -c b-16be.strings | head
0000000  376 377  \0   /  \0   *  \0   *  \0   *  \0     001  \f  \0   E

$ od -c b-16le-BAD-fromUTF16BE.strings | head                                
0000000    /  \0   *  \0   *  \0   *  \0      \0  \f 001   E  \0   S  \0

$ od -c b-16le-BAD-fromUTF8.strings | head
0000000    /  \0   *  \0   *  \0   *  \0      \0  \f 001   E  \0   S  \0
Run Code Online (Sandbox Code Playgroud)

很明显,每当我运行转换为UTF-16LE时,BOM都会丢失.对此有何帮助?

Kei*_*son 36

UTF-16LE告诉iconv生成小端UTF-16 没有一个BOM(字节顺序标记).显然,它假设自您指定以来LE,BOM不是必需的.

UTF-16告诉它 BOM 生成UTF-16文本(在本地机器的字节顺序中).

如果您使用的是小端机器,我看不到iconv用BOM来生成大端UTF-16的方法,但我可能只是遗漏了一些东西.

我发现该file命令无法识别没有BOM的UTF-16文本,而您的编辑器也可能不会.但是如果你运行iconv -f UTF-16LE -t UTF_8 b-16 strings,你应该获得原始文件的有效UTF-8版本.

尝试运行od -c文件以查看其实际内容.

更新:

看起来你是在一台大端机器上(x86是小端),而你正试图生成带有BOM的小端UTF-16文件.那是对的吗?据我所知,iconv不会直接这样做.但这应该工作:

( printf "\xff\xfe" ; iconv -f utf-8 -t utf-16le UTF-8-FILE ) > UTF-16-FILE
Run Code Online (Sandbox Code Playgroud)

printf 可能的行为取决于您的区域设置; 我有LANG=en_US.UTF-8.

(任何人都可以提出更优雅的解决方案吗?)

另一种解决方法,如果您知道由-t utf-16以下产生的输出的字节顺序:

iconv -f utf-8 -t utf-16 UTF-8-FILE | dd conv=swab 2>/dev/null
Run Code Online (Sandbox Code Playgroud)