6

500MBを超える大きなログファイルを生成するアプリケーションがあります。

私はPythonでいくつかのユーティリティを作成しました。これにより、ログファイルをすばやく参照して、目的のデータを見つけることができます。しかし、ファイルが大きすぎてすべてをメモリにロードできないデータセットを取得するようになりました。

したがって、ドキュメントを1回スキャンし、インデックスを作成してから、一度に確認するドキュメントのセクションのみをメモリにロードします。

これは、「ファイル」を開いて一度に1行ずつ読み取り、from file.tell()でオフセットを保存するときに機能します。その後、file.seek(offset、0)を使用して、ファイルのそのセクションに戻ることができます。

ただし、私の問題は、ログファイルにUTF-8が含まれている可能性があるため、コーデックモジュール(codecs.open(<filename>, 'r', 'utf-8'))で開く必要があることです。結果のオブジェクトを使用して、seekとtellを呼び出すことができますが、それらは一致しません。

コーデックは何らかのバッファリングを行う必要があると思いますか、それとも、tellからのバイトではなく文字数を返すのでしょうか?

これを回避する方法はありますか?

4

4 に答える 4

2

UTF-8 の場合、実際に codecs.open でファイルを開く必要はありません。代わりに、最初にファイルをバイト文字列として読み取り、次に個々のセクションをデコードする (文字列に対して .decode メソッドを呼び出す) 方が確実です。行の境界でファイルを分割しても安全です。それを分割する唯一の危険な方法は、マルチバイト文字 (バイト値 > 128 から認識できます) の途中です。

于 2009-10-02T15:32:08.610 に答える
1

Python で UTF8 を使用して行われていることの多くは、Python 3 でどのように行われたかを見れば理にかなっています。あなたの場合、Dive into Python 3: http: //diveintopython3.org/files.html

ただし、要するに、Unicode 文字は複数のバイトを占有する可能性があるのに対し、バイト位置で機能しますfile.seekfile.tellしたがって、次の場合:

f.seek(10)
f.read(1)
f.tell()

17読み取った 1 文字の長さによっては、以外のものを簡単に取得できます。

于 2009-10-02T16:03:55.297 に答える
0

更新: codec.open() によって返されたオブジェクトに対して seek/tell を実行することはできません。通常のファイルを使用し、読み取り後に文字列をユニコードにデコードする必要があります。

なぜうまくいかないのかわかりませんが、うまくいかないのです。たとえば、シークは一度しか機能しないようです。次に、ファイルを閉じて再度開く必要がありますが、これはもちろん役に立ちません。

tell は文字位置を使用しませんが、ストリーム内の位置を示しません (ただし、ディスクから読み取り中の基になるファイル オブジェクトはおそらくどこにありますか)。

したがって、おそらく何らかの基本的なバッファリングが原因で、それを行うことはできません. しかし、読み取り後のデコードは問題なく機能するので、それを行ってください。

于 2009-10-02T15:36:01.770 に答える