2009-06-18 41 views
2

FileDesciptorの.sync()メソッドでjavadocを読むと、sync()は主に、変更されたバッファを元のストレージにコミットすることに関係していることが明らかです。つまり、あなたのプログラムがの出力であるを実際にディスク(またはソケットまたはwhat-have-youですが、私の質問は主にディスクに関係します)にすることを確認してください。JavaのFileDescriptor .sync()の読み込み*ファイルの読み込み

しかし、他の方向については、INPUTはどうですか?私のプログラムがメモリにバッファされたjava.io.RandomAccessFileのいくつかの部分を持っていて、ファイルのそれらの部分を読みたいと思いますが、私のプログラムがそれらのブロックを最後に読み込んだので、

これは、Cプログラムで変数を 'volatile'としてマークするのと同じですが、他の何かが単にあなたの便利なコピーを持っているものの「本物の版」を変えたかもしれません。

私は、あなたのJavaプログラムが読んでいるものが少なくとも合理的に最新のものであることをどのように確かめることができますか?

(明らかに、「最新のもの」の定義。例として、純粋に例として、1秒に1回のオーダーで他のプロセスがファイルに書き込むと仮定します。このような状況では、パフォーマンスはそれほど重要ではありません。読者が読んだものが、書込みが何秒間に何回書いたものであるかを確認することの問題です。

答えて

2

ファイルを読み直す前に、File.lastModified()でファイルの最終更新タイムスタンプを確認することをお勧めします。このタイムスタンプがファイルを最後に読み込んだときよりも新しいものでない場合は、関心のあるブロックを再読み込みするために、より多くのディスクI/Oを気にする必要はありません。最後に変更されたタイムスタンプは、ネットワークファイルシステムを使用している場合にコンテンツが更新されたときに、ただちに更新されるとは限りません。ファイルを更新するローカルプロセスと、コードを実行している別のローカルプロセスを処理してファイルを読み込んでいる場合、この問題はほとんど発生しません。

私が過去に成功した方法の1つは、別のスレッドに特定の間隔、たとえば5秒で最後に変更されたタイムスタンプをポーリングすることでした。ファイルが変更された場合は、ファイルを再処理し、登録済みのリスナーにイベントを送信します。私の場合は、すぐに更新を取得するのに5秒以上の時間がかかりました。

1

ファイルが内部バッファに読み込まれる瞬間、その内容はディスク上の内容に最新のものとなります。

次のアクセス時に最新の内容を確実に保持したい場合は、すべての内部バッファとキャッシュをスキップしてディスクに再度アクセスする必要があります。あなたが本当に確かめたいのであれば、そのようなレイヤーはすべてスキップされます。最初からファイルを開いて、アクセスしたい位置に移動する必要があります。

もちろん、データにアクセスするたびにディスクにアクセスすると、パフォーマンスが低下します。 3-5倍程度ではなく、大きさのオーダーを考えてください。

+0

「ファイルが更新されたときに私に尋ねる」というものはありませんか? – Pacerier

+0

Java 7まではありません。詳細は別の質問をご覧ください:http://stackoverflow.com/a/494886/57601 – Kosi2801

0

あなたが制御する別のプログラムがファイルに書き込む唯一のプログラムであれば、おそらく同じJavaプロセス座標内に2つのスレッドを持つのが最善です。最も簡単な解決策は、java.util.concurrrent.atomic.AtomicBooleanを作成することです。ライタースレッドはAtomicBooleanset(true)を呼び出し、リーダーはgetAndSet(false)を呼び出します。 getAndSet()trueを返す場合、読者はデータを再読する必要があることを知っています。それが問題ならば、読者が読んでいる間にライターが書くのを防ぐために、あるオブジェクトを同期させることができます。

あなたは質問の中で "処理中"と言っていますので、データを変更するシステム上の他のプロセスが心配です。この場合、データを再オープンして再読み込みするのが最善の策だと思います。実際に1分間に1回しか読んでいない場合、このパフォーマンスの影響は無視してください。