0

基本的に、次のようなテキスト ファイルを取得する必要があります。

フレッド・
バーニー・
ヘンリー

ファイルから順番に読み取ることができます

ヘンリー
・バーニー
・フレッド

私が読んでいる実際のファイルは30MBを超えており、ファイル全体を読み取り、配列に分割し、配列を逆にしてそこから移動するのは完全な解決策ではありません。時間がかかりすぎます。私の具体的な目標は、最初に出現する文字列 (この場合は "InitGame") を見つけて、その行の先頭の位置を返すことです。

私は以前にPythonでこのようなことをしました。私の方法は、ファイルの最後 (1024) までシークし、最後に到達するまで行を読み取り、前の開始点から別の 1024 をシークし、tell() を使用して、前の行に到達したときに停止することでした。出発点。そのため、探しているテキストが見つかるまで、これらのブロックをファイルの末尾から逆方向に読み取ります。

これまでのところ、Java でこれを行うのにかなりの時間を費やしています。ボルチモアの近くに住んでいる場合は、焼きたてのクッキーを手に入れることになるかもしれません。

ありがとう!

より詳しい情報:

私が読んでいるファイルは、私がサーバーをホストしているゲームのログファイルであるため、逆方向に検索する必要があります (これは、アーバン テラーの |err| サーバーです。チェックしてください)。ログ ファイルはゲームで発生するすべてのイベントを記録し、プログラムは各イベントを解析して処理し、それに基づいて行動します (たとえば、人々のヘッドショットを追跡し、d バッグである人々を自動的にキックします)。 )。最新の InitGame エントリまでさかのぼって検索し、すべてのプレーヤー オブジェクトをインスタンス化して、そのゲームの開始以降に処理する必要があったものをすべて処理できるようにする必要があります。ファイルには何百もの InitGame イベントがありますが、最後のイベントが必要です。逆方向に検索する必要のない、これを行うためのより良い方法があれば、私に知らせてください。

ありがとう

4

4 に答える 4

1

RandomAccessFile を使用して Python ソリューションを繰り返すことができ、その上に LineNumberReader (または単に Reader) のカスタム サブクラスを作成できます。

于 2010-04-03T16:03:46.860 に答える
0

そのため、自分が何をしているのかを正確に説明するときは、もっと冗長にする必要があります。基本的に、私が実行しているゲームサーバーを管理するプログラムを書いています。プログラムがゲームと同期するためには、最新の InitGame 行を見つけてそこから読み取る必要があります。これにより、ラウンドの開始から必要なすべてのヒット、キル、接続、切断を記録できるようになります。 . ログファイルは非常に巨大になる可能性があるため (前回クリーンアップするのを忘れたときは 500MB 以上のテキストでした)、前から検索するのではなく、後ろから検索したいと考えています。Java では、これを行う組み込みの方法はありませんでした。かなりの量のインターネットを検索した後、私はこれに出くわしました: http://mattfleming.com/node/11. そこから BackwardsFileInputStream クラスを取り出して使用しました。次に、アプリケーションで文字を逆にします。次回は、独自の方法を構築できるようになるはずです。これで、それがどのように行われるかがわかり、理解が深まりました。

そのため、プログラムが最新の InitGame からログ ファイルを読み取ると、tail -f を模倣し、書き込まれたとおりにログ ファイルを読み取ります。

于 2010-04-05T13:28:52.070 に答える
0

Linux には優れたテキスト解析ツールがいくつかあり、Java で行うよりも適している可能性があります。

于 2010-04-03T17:09:42.453 に答える
0

逆に検索すると、2つの答えが思い浮かびます。1 つ目は、順方向に検索し、最後に見つかった InitGame テキストをファイルの最後に到達するまで保持することです (ファイルを読んでいるときに別の InitGame が来るたびに上書きします)。

2 番目の解決策は、(f.length() を使用して) ファイル サイズを調べ、それを InitGame スニペットの最大サイズを超えてオーバーラップする大きなチャンクに分割することです (2 つのチャンクを適切な場所で分割することによる問題を回避するため)。部分)、最後のものから読み取りを開始し、ファイルの先頭に向かって進みます (Reader の skip() 関数を使用して、目的の読み取り位置にジャンプします。実際のファイル分割は必要ありません)。おかしなマルチバイト文字がないことが確実な場合は、RandomAccessFile が役立ちます。

もちろん、最も効率的な解決策は、最後に見つかった InitGame への参照を保持しながら、出力されたログ ファイル出力を読み取ることです。そうすれば、同じデータを 2 回読み直す必要がなくなります。Java プログラムが数秒ごとに起動し、ファイルを調べて、新しく追加された行を読み取るように設定することもできます。

于 2010-04-04T22:47:06.767 に答える