Python 2.7 から Unicode テキストをロードする正しい方法は次のようになります。
content = open('filename').read().decode('encoding'):
for line in content.splitlines():
process(line)
(更新:いいえ、そうではありません。回答を参照してください。)
ただし、ファイルが非常に大きい場合は、一度に 1 行ずつ読み取ってデコードし、処理して、ファイル全体が一度にメモリに読み込まれないようにする必要があります。何かのようなもの:
for line in open('filename'):
process(line.decode('encoding'))
開いているファイルハンドルに対するfor
ループの反復は、一度に 1 行ずつ読み取るジェネレーターです。
たとえば、ファイルが utf32 でエンコードされている場合、ファイル内のバイト (16 進数) は次のようになるため、これは機能しません。
hello\n = 68000000(h) 65000000(e) 6c000000(l) 6c000000(l) 6f000000(o) 0a000000(\n)
そして、for
ループによって行われる行への分割0a
は、文字のバイトで分割され\n
、結果は (16 進数で):
lines[0] = 0x 68000000 65000000 6c000000 6c000000 6f000000 0a
lines[1] = 0x 000000
したがって、\n
文字の一部は 1 行目の最後に残り、残りの 3 バイトは 2 行目に残ります (2 行目に実際にあるテキストが続きますdecode
) UnicodeDecodeError
。
UnicodeDecodeError: 'utf32' codec can't decode byte 0x0a in position 24: truncated data
したがって、明らかに、Unicode バイト ストリームを0a
バイト単位で分割することは、それを行に分割する正しい方法ではありません。代わりに、完全な 4 バイトの改行文字 (0x0a000000) の発生で分割する必要があります。ただし、これらの文字を検出する正しい方法は、バイト ストリームを Unicode 文字列にデコードして文字を探すことだと思います\n
。この完全なストリームのデコードは、まさに私が回避しようとしている操作です。
これは珍しい要件ではありません。それを処理する正しい方法は何ですか?