5

非常に大きなASCIIファイルを「マップ」しようとしています。基本的に、特定のタグが見つかるまで行を読み、そのタグの位置を知りたいので、後でもう一度検索して関連データを引き出すことができます。

from itertools import dropwhile
with open(datafile) as fin:
    ifin = dropwhile(lambda x:not x.startswith('Foo'), fin)
    header = next(ifin)
    position = fin.tell()

今、これtellは私に正しい位置を与えません。この質問は、以前にさまざまな形で尋ねられました。その理由はおそらく、python がファイル オブジェクトをバッファリングしているためです。したがって、python は、ファイル ポインタがどこにあるかではなく、ファイル ポインタがどこにあるかを教えてくれます。 このバッファリングをオフにしたくない... ここでのパフォーマンスは重要です。ただし、python がバッファすることを選択したバイト数を決定する方法があるかどうかを知っておくとよいでしょう。私の実際のアプリケーションでは、 で始まる行を閉じていればFoo問題ありません。あちこちに数行をドロップできます。だから、私が実際にやろうとしていることは次のようなものです:

position = fin.tell() - buffer_size(fin)

バッファサイズを見つける方法はありますか?

4

1 に答える 1

2

私には、バッファー サイズがCpython で 8192 にハードコーディングされているように見えます。私が知る限り、ファイルを開いたときに 1 行を読み取る以外に、Python インターフェイスからこの数値を取得する方法はありません。 、f.tell()Pythonが実際に読み取ったデータの量を把握するために a を実行し、続行する前にファイルの先頭に戻ります。

with open(datafile) as fin:
    next(fin)
    bufsize = fin.tell()
    fin.seek(0)

    ifin = dropwhile(lambda x:not x.startswith('Foo'), fin)
    header = next(ifin)
    position = fin.tell()

もちろん、これは最初の行のさが 8192 バイトを超える場合は失敗しますが、それは私のアプリケーションにとって実際の結果ではありません。

于 2013-04-13T02:53:30.710 に答える