UnicodeDecodeError:数据意外结束



我有一个巨大的文本文件要打开
我正在分块读取文件,避免了同时读取过多文件所带来的内存问题。

代码片段:

def open_delimited(fileName, args):
    with open(fileName, args, encoding="UTF16") as infile:
        chunksize = 10000
        remainder = ''
        for chunk in iter(lambda: infile.read(chunksize), ''):
            pieces = re.findall(r"(d+)s+(d+_d+)", remainder + chunk)
            for piece in pieces[:-1]:
                yield piece
            remainder = '{} {} '.format(*pieces[-1]) 
        if remainder:
            yield remainder

则代码抛出错误CCD_ 1。

我尝试了UTF8,得到了错误UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte

latin-1iso-8859-1引发错误IndexError: list index out of range

输入文件示例:

b'xffxfe1x000x000x005x009x00tx001x000x000x005x009x00_x009x007x004x007x001x007x005x003x001x000x009x001x00tx00tx00Px00ox00sx00tx00tx001x00tx00Hx00ax00px00px00yx00 x00Bx00ix00rx00tx00hx00dx00ax00yx00tx002x000x001x001x00-x000x008x00-x002x004x00 x00'

我还将提到,我有几个这样巨大的文本文件
UTF16对它们中的许多都很好,但在特定文件中会失败。

无论如何要解决这个问题?

要忽略损坏的数据(这可能导致数据丢失),请在open()调用上设置errors='ignore'

with open(fileName, args, encoding="UTF16", errors='ignore') as infile:

UnicodeDecodeError: 'utf16' codec can't decode bytes in position 8190-8191: unexpected end of data0功能文档规定:

  • 'ignore'忽略错误。请注意,忽略编码错误可能会导致数据丢失

这并不意味着你可以从你正在经历的明显的数据损坏中恢复。

为了举例说明,假设在文件中的某个地方删除或添加了一个字节。UTF-16是一种每字符使用2个字节的编解码器。如果有一个字节丢失或多余,那么丢失或多余字节后面的所有字节对都将不对齐。

这可能会导致进一步解码的问题,而不一定是立即解码。UTF-16中有一些代码点是非法的,但通常是因为它们与另一个字节对组合使用;您的异常是为这样一个无效的代码点引发的。但是,在该点之前可能有数百或数千个字节对是有效的UTF-16,如果不是易读的文本的话。

我也在做同样的事情(以块的形式读取许多大型文本文件),但其中一个文件遇到了同样的错误:

Traceback (most recent call last):
  File "wordcount.py", line 128, in <module>
    decodedtext = rawtext.decode('utf8')
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc2 in position 9999999: unexpected end of data

以下是我的发现:问题是一个跨越两个块的特定Unicode序列(xc2xa0xc2xa0)。因此,这个序列被分割,变得不可解码。以下是我解决问题的方法:

# read text
rawtext = file.read(chunksize)
# fix splited end
if chunknumber < totalchunks:
    while rawtext[-1] != ' ':
        rawtext = rawtext + file.read(1)
# decode text
decodedtext = rawtext.decode('utf8')

这也解决了单词跨越两个块时被切成两半的更普遍的问题。

在Python 3中,当您读取/写入io.StringIO对象而不是io.BytesIO 时,也可能发生这种情况

最新更新