5

tell()GBK でエンコードされた私のファイルの読み取り中に呼び出すと、次の呼び出しreadline()UnicodeDecodeError. ただし、 を呼び出さないとtell()、このエラーは発生しません。

C:\tmp>hexdump badtell.txt

000000: 61 20 6B 0D 0A D2 BB B0-E3                       a k......

C:\tmp>test.py と入力

with open(r'c:\tmp\badtell.txt', "r", encoding='gbk') as f:
    while True:
        pos = f.tell()
        line = f.readline();
        if not line: break
        print(line)

C:\tmp>python test.py

a k

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    line = f.readline();
UnicodeDecodeError: 'gbk' codec can't decode byte 0xd2 in position 0:  incomplete multibyte sequence

ステートメントを削除すると、f.tell()正常にデコードされました。なんで?Win7/Win10 で Python3.4/3.5 x64 を試してみましたが、すべて同じです。

誰か、何か考えはありますか?バグを報告する必要がありますか?

大きなテキスト ファイルがあり、この大きなテキストのファイル位置範囲を取得したいのですが、回避策はありますか?

4

2 に答える 2

2

OK、回避策があります。これまでのところ動作します:

with open(r'c:\tmp\badtell.txt', "rb") as f:
    while True:
        pos = f.tell()
        line = f.readline();
        if not line: break
        line = line.decode("gbk").strip('\n')
        print(line)

昨日ここに問題を提出しました:http://bugs.python.org/issue26990

まだ返事がない

于 2016-05-11T08:36:27.307 に答える
2

Linux 上の Python 3.4 x64 でこれを複製しました。のドキュメントを見ると、ファイルの読み取りに問題を引き起こすTextIOBaseと書かれているものは何もないtell()ので、実際にはバグである可能性があります。

b'\xd2'.decode('gbk')

見たようなエラーが発生しますが、ファイルでは、そのバイトの後に byte が続きBB

b'\xd2\xbb'.decode('gbk')

エラーではなく、に等しい値を返し'\u4e00'ます。

元の質問のデータでは機能するが、他のデータでは機能しない回避策を見つけました。理由を知りたい!私は返された値で、seek()ごとに呼び出しました:tell()tell()

pos = f.tell()
f.seek(pos)
line = f.readline()

の代わりに、 のモードf.seek(f.tell())を使用して位置を指定することもできます。オフセットが 0 の場合、これは上記のコードと同じことを行います。現在の位置に移動し、その位置を取得します。SEEK_CURseek()

pos = f.seek(0, io.SEEK_CUR)
line = f.readline()
于 2016-05-10T15:13:12.583 に答える