【发布时间】:2012-08-05 16:24:54
【问题描述】:
从 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 循环完成的拆分成行在\n 字符的0a 字节上拆分,导致(十六进制):
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 字符 - 而这种对完整流的解码正是我试图避免的操作。
这不是不常见的要求。正确的处理方法是什么?
【问题讨论】:
-
您是否尝试使用 codecs.open() 方法读取文件?
-
@Maulwurfn,我不知道它存在!但我现在这样做。谢谢。
标签: python python-2.7 file-io unicode generator