1

我在 Python 2.7.2 中有一个字符串说 u"\u0638"。当我将其写入文件时:

f = open("J:\\111.txt", "w+")
f.write(u"\u0638".encode('utf-16'))
f.close()

在十六进制中它看起来像:FF FE 38 06 当我将这样的字符串打印到标准输出时,我会看到:'\xff\xfe8\x06'。

问题: 输出到stdout的字符串中的\x38在哪里?换句话说,为什么输出到标准输出的字符串不是'\xff\xfe\x38\x06'?

如果我将字符串写入文件两次:

f = open("J:\\111.txt", "w+")
f.write(u"\u0638".encode('utf-16'))
f.write(u"\u0638".encode('utf-16'))
f.close()

文件中的十六进制表示包含字节顺序标记 (BOM) \xff\xfe两次:FF FE 38 06 FF FE 38 06

我想知道避免在 UTF-16 编码字符串中写入 BOM 的技术是什么?

4

3 回答 3

5

ASCII 字符8具有十六进制表示0x38。所以你的字符串:

\xff\xfe8\x06

四个字节长。以空格分隔,字节为:

\xff \xfe 8 \x06

Python 使用\x不代表可打印 ASCII 字符的字节表示法。

于 2012-06-25T21:14:04.370 回答
3

编码为“utf-16le”或“utf-16be”(小端或大端)应跳过编写 BOM。当然,如果没有 BOM,解码器需要知道预期的字节顺序。

于 2012-06-25T21:21:02.783 回答
1

\xff\xfe8\x06 确实包含\x388== \x38

对于您的第二个问题,为了避免 BOM,如果您明确说明字节顺序(使用UTF-16BEUTF-16LE编解码器),则不会打印任何 BOM。

但是,正确的做法是使用为您处理编码和解码的文件包装器,并在您的程序中使用 unicode。在 Python 3.0 中,open内置函数可以这样做:

fp = open(filename, 'w', encoding='utf-16')
fp.write(u'write one line\n')
fp.write(u'write another line\n')
fp.close()

在 Python 2.x 中,使用编解码器包装器:

fp = codecs.open(filename, 'w', 'utf-16')
fp.write(u'write one line\n')
fp.write(u'write another line\n')
fp.close()
于 2012-06-25T21:43:52.470 回答