我有一个巨大的文本文件,我想打开。
我正在以块的形式读取文件,避免了与一次读取过多文件相关的内存问题。
代码段
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
代码抛出错误UnicodeDecodeError: 'utf16' codec can't decode bytes in position 8190-8191: unexpected end of data
。
我尝试UTF8
并收到错误UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte
。
latin-1
和iso-8859-1
引发了错误IndexError: list index out of range
输入文件的示例:
b'\xff\xfe1\x000\x000\x005\x009\x00\t\x001\x000\x000\x005\x009\x00_\x009\x007\x004\x007\x001\x007\x005\x003\x001\x000\x009\x001\x00\t\x00\t\x00P\x00o\x00s\x00t\x00\t\x001\x00\t\x00H\x00a\x00p\x00p\x00y\x00 \x00B\x00i\x00r\x00t\x00h\x00d\x00a\x00y\x00\t\x002\x000\x001\x001\x00-\x000\x008\x00-\x002\x004\x00 \x00'
我还要提到我有几个巨大的文本文件
UTF16
适用于其中许多人,并且在特定文件中失败。
无论如何要解决这个问题?
答案 0 :(得分:6)
要忽略损坏的数据(可能导致数据丢失),请在errors='ignore'
电话上设置open()
:
with open(fileName, args, encoding="UTF16", errors='ignore') as infile:
open()
function documentation州:
'ignore'
忽略错误。请注意,忽略编码错误可能会导致数据丢失。
这并不意味着您可以从正在经历的明显数据损坏中恢复。
为了说明,假设一个字节被删除或添加到文件中的某个位置。 UTF-16是一个每个字符使用2个字节的编解码器。如果有一个字节丢失或过剩,则丢失或额外字节后面的所有字节对都将不对齐。
这可能导致在线下进一步解码的问题,不一定立即。 UTF-16中有一些代码点是非法的,但通常是因为它们与另一个字节对组合使用;您的异常被抛出了这样一个无效的代码点。但是在该点之前可能有数百或数千个字节对是有效的UTF-16,如果不是清晰易读的话。
答案 1 :(得分:3)
我正在做同样的事情(以块的形式阅读许多大型文本文件)并且与一个文件遇到同样的错误:
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序列(\xc2\xa0\xc2\xa0
)。因此,该序列被拆分并变得不可解码。这就是我解决它的方法:
# 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')
这也解决了当它们跨越两个块时被切成两半的更普遍的问题。
答案 2 :(得分:0)
在Python 3中,当您读/写io.StringIO
对象而不是io.BytesIO
时也会发生这种情况