11

開きたい巨大なテキスト ファイルがあります。
一度に大量のファイルを読み取ることに関連するメモリの問題を回避して、ファイルをチャンクで読み取っています。

コードスニペット:

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-1iso-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それらの多くでは問題なく動作し、特定のファイルで失敗します。

とにかくこの問題を解決するには?

4

3 に答える 3

9

破損したデータ (データの損失につながる可能性があります) を無視するには、呼び出しで次のように設定errors='ignore'します。open()

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

open()関数のドキュメントには次のように記載されています。

  • 'ignore'エラーを無視します。エンコード エラーを無視すると、データが失われる可能性があることに注意してください。

これは、発生している明らかなデータ破損から回復できるという意味ではありません。

説明のために、ファイルのどこかにバイトが削除または追加されたと想像してください。UTF-16 は、1 文字あたり 2 バイトを使用するコーデックです。1 バイトの欠落または余剰がある場合、欠落または余分なバイトに続くすべてのバイトペアが整列しなくなります。

これにより、必ずしもすぐにではなく、後でデコードの問題が発生する可能性があります。UTF-16 には不正なコードポイントがいくつかありますが、通常は別のバイトペアと組み合わせて使用​​されるためです。そのような無効なコードポイントに対して例外がスローされました。しかし、そのポイントの前に、判読可能なテキストではないにしても、有効な UTF-16 である数百または数千のバイトペアがあった可能性があります。

于 2013-08-21T14:39:54.437 に答える
3

私は同じことをしていました(チャンクで多くの大きなテキストファイルを読んでいます)、ファイルの1つで同じエラーに遭遇しました:

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

私が見つけたものは次のとおりです。問題は、\xc2\xa0\xc2\xa02 つのチャンクにまたがる特定の Unicode シーケンス ( ) でした。したがって、そのシーケンスは分割され、解読不能になりました。これが私がそれを解決した方法です:

# 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 つのチャンクにまたがる場合に単語が半分にカットされるという、より一般的な問題も解決されます。

于 2013-10-05T17:25:28.787 に答える
0

io.StringIOこれは、Python 3 でオブジェクトの読み取り/書き込みを行うときにも発生する可能性があります。io.BytesIO

于 2018-07-18T21:03:56.043 に答える