如何在Python 3中读取包含Unicode的大文件

1 投票
1 回答
2121 浏览
提问于 2025-04-17 12:05

你好,我有一个很大的文件,里面包含了Unicode字符。当我尝试在Python 3中打开它时,遇到了这个错误。

文件 "addRNC.py",第47行,在 add_rnc()

文件 "addRNC.py",第13行,在 init 对于 rawDoc.readline() 中的每个值:

文件 "/usr/local/lib/python3.1/codecs.py",第300行,在 decode (result, consumed) = self._buffer_decode(data, self.errors, final)

UnicodeDecodeError: 'utf8' 编解码器无法解码位置158的字节0xd3:无效的继续字节

我尝试了所有方法,但都没有成功,这里是代码:

rawDoc = io.open("/root/potential/rnc_lst.txt", 'r', encoding='utf8')
    result = []
    for value in rawDoc.readline():

        if len(value.split('|')[9]) > 0 and len(value.split('|')[10]) > 0: 
            if value.split('|')[9] == 'ACTIVO' and value.split('|')[10] == 'NORMAL':
                address = ''
                for piece in value.split('|')[4:7]:
                    address += piece
                if value.split('|')[8] != '':
                    rawdate = value.split('|')[8].split('/')
                    _date = rawdate[2]+"-"+rawdate[1]+"-"+rawdate[0]
                else:
                    _date = 'NULL'

                id = db.prepare("SELECT id FROM potentials_reg WHERE(rnc = '%s')"%(value.split('|')[0]))()

                if len(id) == 0:
                    if _date == 'NULL':
                        db.prepare("INSERT INTO potentials_reg (rnc, _name, _owner, work_type, address, telephone, constitution, active)"+ 
                                "VALUES('%s', '%s', '%s', '%s', '%s', '%s', NULL, '%s')"%(value.split('|')[0], value.split('|')[1], 
                                                                        value.split('|')[2],value.split('|')[3],address, 
                                                                        value.split('|')[7], 'true'))()
                    else:
                        db.prepare("INSERT INTO potentials_reg (rnc, _name, _owner, work_type, address, telephone, constitution, active)"+ 
                                "VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')"%(value.split('|')[0], value.split('|')[1], 
                                                                        value.split('|')[2],value.split('|')[3],address, 
                                                                        value.split('|')[7],_date, 'true'))()
                else:
                    pass

    db.close()

1 个回答

5

你的文件实际上包含了无效的UTF-8编码。

当你说“包含Unicode字符”时,要明白Unicode并没有规定这些字符是怎么表示的。所以即使这个文件表示的是Unicode数据,它也可能是用UTF-8、UTF-16(有两种形式:UTF-16BE或UTF-16LE,可能带有或不带有BOM),或者是已经不再使用的UCS-2,甚至可能是一些更复杂的格式……

请仔细检查一下文件是否有效;我敢打赌,你的文件里确实有一个字节0xD3(11010011),在UTF-8中,这个字节必须是一个两字节字符的开头字节,但它却出现在了后面的位置(换句话说,0xD3后面紧跟着一个二进制表示以11开头的字节[大于0xC0])。

最可能的原因是你的文件包含了非ASCII字符,但它并不是用UTF-8编码的。

撰写回答