2

理解できない CPython の問題があります。要するに、同じコードを使用して小さなテキスト ファイルを読み取ることはできますが、20 GB の txt ファイルから 1 行も読み取れないという事実です。

役立つ情報:

  • 小さいファイル ~1MB は、大きな 20GB ファイルのサブセットです (最初から 1MB)。
  • 両方のファイルは、CR (\r) で区切られた幅 ~2000 文字の行を持つテキスト ファイルです。

明白な解決策:

f = open(r'filename', 'r')
for line in f:
    print(line)
f.close()

動作します...しかし..短いファイルのみ。大きなものは永遠にハングアップします(または、少なくとも最初の行を印刷するのにかかる時間よりも長くなります)。

だから私は少なくとも次のような1行を読みたいと思っていました:

f = open(r'filename', 'r')
print(f.readline())
f.close()

ここで同様の状況-小さなファイルではすぐに機能しますが、かなりの時間が経過した後の大きなファイルでは、そのメッセージが吐き出されます。

Traceback (most recent call last):
  File "***", line 16, in <module>
    print(f.readline())
SystemError: ..\Objects\stringobject.c:3902: bad argument to internal function

大きなテキストファイルをどうやって読むべきですか?

アップデート:

人間は十分な睡眠をとっている場合、より明確に考えていることがわかりました;-)。問題は解決されました - ドキュメント内の 1 つの文を見落としていたことが判明しました。

Python は通常、普遍的な改行サポートで構築されています。'U' を指定するとファイルがテキスト ファイルとして開きますが、行は次のいずれかで終了する場合があります: Unix の行末規則 '\n'、Macintosh の規則 '\r'、または Windows の規則 '\ r\n'.

ユニバーサル改行はデフォルトで「オン」になっていると思いました。

私の上記の声明:

print(f.readline())

1行だけ読んでいましたが、部分的に間違っていました(私の悪いことです)。私の小さなファイルは、大きなファイルのチャンクを取得して作成されたと言ったことを覚えていますか? その操作中に行末が (CR) から (CRLF) に変わったので、私が見たのは最初の行でした。そのすべてが、問題は行末にあるのではない、と私に思わせました。

時間と助けてくれてありがとう。

4

2 に答える 2

5

あなたの「テスト」は1行しか出力しませんが、それはファイルから1行しか読み取っていないという意味ではありません。で区切られた\rテスト ファイルでは、出力も 1 行しか得られません。forただし、ループを使用して各行を読み取ると、まだ1 行しか出力されません。または、複数行のファイルでもう一度試しreadline()ても、それ以上行が表示されません。

'rU'同じファイルのパラメーターを使用してファイルを開いてみてください。

f =  open('filename', 'rU')

\rで区切られたテキストが数行あるファイルの私のテストでは、次の結果が得られます。

f = open('test.txt','r')  # Opening the "wrong" way
for line in f:
    print line

出力:

abcdef

次にrU

f = open('test.txt','rU')
for line in f:
    print line

出力:

abcdef

abcdef

abcdef

abcdef

abcdef

編集: Joran の説明をサポートするために、このテストは、ファイル全体が読み込まれており、出力が 1 行しか表示されないときにキャリッジ リターン文字がオーバープリントを引き起こしていることを示しています...

f = open('test.txt','r')     #  Opening the "wrong" way again
for line in f:
    print "XXX{}YYY".format(line)

出力が上書きされます...

YYYdefdef
于 2013-11-07T19:32:23.347 に答える
0
def my_readline(fh,delim):
    return "".join(iter(lambda:fh.read(1),delim))

f = open(some_file)
line = my_readline(f,"\r")

少なくとも.read(1)仕事に取り掛かることができればうまくいくはずです...しかし、それがうまくいかない場合、何かがうまくいくかどうかはわかりません...おそらくシェルコマンドを使用して、ファイルを小さなチャンクに分割します...しかし、ベロエの答えは本物だと思います答え

于 2013-11-07T19:32:10.947 に答える