从 Python 2.7 加载 unicode 文本的正确方法是:
content = open('filename').read().decode('encoding'):
for line in content.splitlines():
process(line)
(更新:不,不是。请参阅答案。)
但是,如果文件非常大,我可能想一次读取、解码和处理一行,这样整个文件就不会一次加载到内存中。就像是:
for line in open('filename'):
process(line.decode('encoding'))
循环在打开的文件句柄上的for
迭代是一个一次读取一行的生成器。
但这不起作用,因为例如,如果文件是 utf32 编码的,那么文件中的字节(十六进制)看起来像:
hello\n = 68000000(h) 65000000(e) 6c000000(l) 6c000000(l) 6f000000(o) 0a000000(\n)
for
并且由循环完成的分割成行分割字符的0a
字节\n
,导致(以十六进制表示):
lines[0] = 0x 68000000 65000000 6c000000 6c000000 6f000000 0a
lines[1] = 0x 000000
因此,部分\n
字符留在第 1 行的末尾,其余三个字节在第 2 行结束(后面是实际在第 2 行中的任何文本。)decode
可以理解的是,调用这些行中的任何一行都会导致UnicodeDecodeError
.
UnicodeDecodeError: 'utf32' codec can't decode byte 0x0a in position 24: truncated data
因此,很明显,将 unicode 字节流拆分为0a
字节并不是将其拆分为行的正确方法。相反,我应该在出现完整的四字节换行符 (0x0a000000) 时进行拆分。但是,我认为检测这些字符的正确方法是将字节流解码为 unicode 字符串并查找\n
字符——而这种对完整流的解码正是我试图避免的操作。
这不能是一个不常见的要求。正确的处理方法是什么?