我知道这个问题有很多解决方案,但我的意思是,我可能会截断utf16数据并且必须尽最大努力处理解码和编码因UnicodeDecodeError而失败的转换。所以在python中提出了以下代码。 请让我知道您对如何改进它们以加快处理速度的评论。
try:
# conversion to ascii if utf16 data is formatted correctly
input = open(filename).read().decode('UTF16')
asciiStr = input.encode('ASCII', 'ignore')
open(filename).close()
return asciiStr
except:
# if fail with UnicodeDecodeError, then use brute force
# to decode truncated data
try:
unicode = open(filename).read()
if (ord(unicode[0]) == 255 and ord(unicode[1]) == 254):
print("Little-Endian format, UTF-16")
leAscii = "".join([(unicode[i]) for i in range(2, len(unicode), 2) if 0 < ord(unicode[i]) < 127])
open(filename).close()
return leAscii
elif (ord(unicode[0]) == 254 and ord(unicode[1]) == 255):
print("Big-Endian format, UTF-16")
beAscii = "".join([(unicode[i]) for i in range(3, len(unicode), 2) if 0 < ord(unicode[i]) < 127])
open(filename).close()
return beAscii
else:
open(filename).close()
return None
except:
open(filename).close()
print("Error in converting to ASCII")
return None
答案 0 :(得分:3)
怎么样:
data = open(filename).read()
try:
data = data.decode("utf-16")
except UnicodeDecodeError:
data = data[:-1].decode("utf-16")
即。如果它在代码单元中途被截断,则剪掉最后一个字节,然后重新执行。这应该让你回到有效的UTF-16字符串,而不必自己尝试实现解码器。
答案 1 :(得分:2)
为了容忍错误,您可以使用字节字符串的decode方法的可选第二个参数。在这个例子中,悬空的第三个字节('c')被替换为“替换字符”U + FFFD:
>>> 'abc'.decode('UTF-16', 'replace')
u'\u6261\ufffd'
还有一个'ignore'选项,它只会删除无法解码的字节:
>>> 'abc'.decode('UTF-16', 'ignore')
u'\u6261'
虽然通常希望系统“容忍”错误编码的文本,但通常很难准确定义在这些情况下预期行为是什么。您可能会发现提供“处理”错误编码文本的要求的人并不完全掌握字符编码的概念。
答案 2 :(得分:-1)
这只是作为“最佳实践”改进而跳出来的。文件访问应该真正包含在with
块中。这将为您打开和清理。