4

对于输入文本文件,我知道 .seek 和 .tell 通常都使用字节进行操作 - 也就是说,.seek 查找与其给定参数指定的点相关的一定数量的字节,并且 .tell 返回字节数从文件开始。

我的问题是:在使用其他编码(如 utf-8)时,这是否同样有效?例如,我知道 utf-8 需要几个字节来表示某些字符。

看起来,如果这些方法在解析 utf-8 文件时仍然处理字节,则可能会导致意外行为(例如,光标可能最终位于字符的多字节编码中,或者多字节字符可能注册为几个字符)。

如果是这样,是否有其他方法可以完成相同的任务?特别是在解析文件时需要有关光标位置的字符信息。

另一方面,如果您在 open() 函数中指定编码...

infile = 打开(文件名,编码='utf-8')

.seek 和 .tell 的行为会改变吗?

4

2 回答 2

2

假设您正在使用io.open()(与 builtin 不同open()),那么使用文本模式可以获得 a 的实例io.TextIO,所以这应该回答您的问题:

二进制存储(例如文件)上的文本 I/O 比相同存储上的二进制 I/O 慢得多,因为它意味着使用字符编解码器从 unicode 转换为二进制数据。如果您处理大量文本数据(例如非常大的日志文件),这可能会变得很明显。此外, 由于使用了重建算法,TextIOWrapper.tell() 和TextIOWrapper.seek()都非常慢。

注意:您还应该知道,这仍然不能保证 seek() 会跳过字符,而是 unicode 代码点(单个字符可以由多个代码点组成,例如ą可以写为u'\u0105'u'a\u0328'-两者都将打印相同的字符)。

来源:http ://docs.python.org/library/io.html#id1

于 2012-06-26T14:53:25.547 回答
1

对 utf-8 编码的一些实验(在具有大量多字节字符的文件中重复查找和打印 .read(1) 方法)表明,是的,.seek() 和 .read() 在 utf-8 中的行为确实不同文件...它们不处理单个字节,而是单个字符。这包括几个简单的代码重写,以不同的模式阅读和寻找。

感谢@satuon 的帮助。

于 2012-06-26T14:51:47.247 回答