Python - 解码带BOM的UTF-16文件

22
我有一个带有BOM的UTF-16 LE文件。我想将其转换为不带BOM的UTF-8文件,以便我可以使用Python解析它。
通常我使用的代码并没有起作用,它返回了未知字符而不是实际的文件内容。
f = open('dbo.chrRaces.Table.sql').read()
f = str(f).decode('utf-16le', errors='ignore').encode('utf8')
print f

如何正确解码这个文件,以便我可以使用 f.readlines() 解析它?


1
如果您在Windows上操作,请尝试以二进制模式打开文件,看看是否有所帮助。 - Mark Ransom
2个回答

24

首先,您应该以二进制模式阅读,否则会令事情变得混淆。

然后,请检查并删除BOM,因为它是文件的一部分,但不属于实际文本。

import codecs
encoded_text = open('dbo.chrRaces.Table.sql', 'rb').read()    #you should read in binary mode to get the BOM correctly
bom = codecs.BOM_UTF16_LE                                      #print dir(codecs) for other encodings
assert encoded_text.startswith(bom)                           #make sure the encoding is what you expect, otherwise you'll get wrong data
encoded_text = encoded_text[len(bom):]                         #strip away the BOM
decoded_text = encoded_text.decode('utf-16le')                 #decode to unicode

在完成所有解析/处理之前,请不要进行编码(如转换为utf-8或其他编码)。您应该使用unicode字符串进行所有操作。

此外,在decode时使用errors='ignore'可能是一个坏主意。考虑哪个更糟:让程序提示错误并停止,还是返回错误的数据?


17

这在 Python 3 中有效:

f  = open('test_utf16.txt', mode='r', encoding='utf-16').read()
print(f)

4
如果您将编码设置为utf-16,则无需手动删除BOM。 - 026
4
编辑后的内容应该是 utf-16 编码,虽然没有官方文档支持,但 utf-16 编码好像可以自动处理 BOM。如果你使用 utf-16le 编码,它仍然能够工作,但是 BOM 会保留在那里,你可以通过使用字符串函数和 codecs.BOM_UTF16_BE 来手动去除它。 - mgrandi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接