Python 如果将seek()搜索到多字节UTF-8字符的中间并调用read(1),会发生什么情况?
在Python 3中,Python 如果将seek()搜索到多字节UTF-8字符的中间并调用read(1),会发生什么情况?,python,utf-8,Python,Utf 8,在Python 3中,read(size)包含以下文档: 作为单个str从流中读取并返回最大大小的字符。如果大小为负数或None,则读取直到EOF 但假设您将seek()添加到多字节UTF-8字符的中间。read(1)返回什么?Python 3中的文本流不支持任意搜索偏移量,您只应该使用偏移量0,或者使用返回的值告诉使用搜索集的从哪里来。其他一切都是未定义或不受支持的行为。看 当然,在实践中,您可能会得到UnicodeDecodeError,但这不是保证。一旦您违反API合同要求,它就可以做任何
read
(size)包含以下文档:
作为单个str
从流中读取并返回最大大小的字符。如果大小为负数或None
,则读取直到EOF
但假设您将
seek()
添加到多字节UTF-8字符的中间。read(1)
返回什么?Python 3中的文本流不支持任意搜索偏移量,您只应该使用偏移量0,或者使用返回的值告诉使用搜索集的从哪里来。其他一切都是未定义或不受支持的行为。看
当然,在实践中,您可能会得到UnicodeDecodeError
,但这不是保证。一旦您违反API合同要求,它就可以做任何它想做的事情。Python 3中的文本流不支持任意搜索偏移量,您只能使用偏移量0,或者使用seek\u SET
的tell
返回的值。其他一切都是未定义或不受支持的行为。看
当然,在实践中,您可能会得到UnicodeDecodeError
,但这不是保证。一旦您违反API合同要求,它可以做任何它想做的事。部分unicode字符无法解码,因此python将引发UnicodeDecodeError
。但你可以从问题中恢复过来。UTF-8编码是自愈的,这意味着字符序列的第一个字节(0x00-0x7f或0xc0-0xfd)将不会出现在任何其他字节中,因此您只需继续向后搜索1个字节,直到解码工作
>>> def read_unicode(fp, position, count):
... while position >= 0:
... fp.seek(position)
... try:
... return fp.read(count)
... except UnicodeDecodeError:
... position -= 1
... raise UnicodeDecodeError("File not decodable")
...
>>> open('test.txt', 'w', encoding='utf-8').write("学"*10000)
10000
>>> f=open('test.txt', 'r', encoding='utf-8')
>>> f.seek(32)
32
>>> f.read(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/codecs.py", line 319, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa6 in position 0: invalid start byte
>>> read_unicode(f, 32, 1)
'学'
def read_unicode(fp、位置、计数):
... 当位置>=0时:
... fp.seek(位置)
... 尝试:
... 返回fp.read(计数)
... 除UNICEDECODEERROR外:
... 位置-=1
... 引发UnicodeDecodeError(“文件不可解码”)
...
>>>打开('test.txt','w',encoding='utf-8')。写入('学"*10000)
10000
>>>f=open('test.txt','r',encoding='utf-8')
>>>f.seek(32)
32
>>>f.read(1)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python3.4/codecs.py”,第319行,解码中
(结果,消耗)=自身缓冲区解码(数据,自身错误,最终)
UnicodeDecodeError:“utf-8”编解码器无法解码位置0中的字节0xa6:无效的开始字节
>>>读取unicode(f,32,1)
'学'
部分unicode字符无法解码,因此python将引发UnicodeDecodeError
。但您可以从问题中恢复。UTF-8编码是为自愈而构建的,这意味着字符序列的第一个字节(0x00-0x7f或0xc0-0xfd)不会出现在任何其他字节中,因此您只需继续向后搜索1个字节,直到解码工作
>>> def read_unicode(fp, position, count):
... while position >= 0:
... fp.seek(position)
... try:
... return fp.read(count)
... except UnicodeDecodeError:
... position -= 1
... raise UnicodeDecodeError("File not decodable")
...
>>> open('test.txt', 'w', encoding='utf-8').write("学"*10000)
10000
>>> f=open('test.txt', 'r', encoding='utf-8')
>>> f.seek(32)
32
>>> f.read(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/codecs.py", line 319, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa6 in position 0: invalid start byte
>>> read_unicode(f, 32, 1)
'学'
def read_unicode(fp、位置、计数):
…当位置>=0时:
…fp.seek(位置)
……试试看:
…返回fp.read(计数)
…UnicodeDecodeError除外:
…位置-=1
…引发UnicodeDecodeError(“文件不可解码”)
...
>>>打开('test.txt','w',encoding='utf-8')。写入('学"*10000)
10000
>>>f=open('test.txt','r',encoding='utf-8')
>>>f.seek(32)
32
>>>f.read(1)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python3.4/codecs.py”,第319行,解码中
(结果,消耗)=自身缓冲区解码(数据,自身错误,最终)
UnicodeDecodeError:“utf-8”编解码器无法解码位置0中的字节0xa6:无效的开始字节
>>>读取unicode(f,32,1)
'学'