2011-12-03 3 views
4

基本的に、新しいJavaの7 WatchServiceを使用してディレクトリを監視しています。Java 7 WatchService:ハンドラのイベントソースを変更するときに無限ループのイベントを回避する

私は、ディレクトリによって発行されたすべてのIOイベントをリスンするハンドラのチェーンを持っています。

ハンドラが何らかの形でIOイベント(==ファイル)の理由を変更する必要があるという問題があります。たとえば、誰かが監視対象のフォルダにファイルを置くと、ハンドラの1つがファイルの拡張子を変更したり、ファイル名に何かを追加したりすることがあります。

これらのアクションはもちろん、新しいIOイベントをトリガーし、前述のハンドラーがそれらを取得します。そして、彼らはもう一度彼らの変更を行います。これは明らかに無限ループにつながります...

Javaはこのような状況を処理する方法を提供していますか?そうでない場合は、どうすればこの問題に対処しますか?

基本的には、イベントハンドラがそのハンドラのアクションによって引き起こされなかった場合にのみイベントハンドラを実行したいと思います。

UPDATE:解決策は、私が書いたすべてのハンドラでこれを心配するのではなく、メインイベントルータのコードだけを変更することです(「ハンドラはそれをしないと変更します前")。

+0

以前の操作に基づいて、ハンドラで無視するイベントを追跡する必要があると思われます。 Mark Elliotの答えが可能な場合は、最も簡単な方法です。 – jontro

答えて

4

これは、基本ケースがない場合、無限ループにつながります。

人がファイルを.barという拡張子でディレクトリに置いて、拡張子 '.foo'をつけたいとしたら、ハンドラはその変更をとします。が現在の拡張子が '.bar'の場合に限ります。

あなたのハンドラはまだ新しい<file>.fooのイベントを取得しますが、それを破棄して「無限の」イベントの伝播を停止することができます。

+0

まだ質問はメリットがあります。監視対象のディレクトリに置かれたすべてのファイルに対してアクションを実行したいとしたら、簡単に検出できない操作を実行するとします。したがって、外部の発信者による変更に対処するだけです。 – jontro

+0

@jontro:あなたが*イベントを自己生成する*場合、その生成が無限ループを引き起こす可能性がある点は、再帰のように基本ケースを持つ必要があります。 –

+0

もちろん、外部の呼び出し元があった場合にのみアクションを取ることは、合理的かつ可能なシナリオのように思える、ということです。私はむしろメインイベントのルータのコードに変更を加えたいと思います。これは私が書いたすべてのハンドラで心配しています。 –

0

イベントを処理するコードが新しいイベントをトリガーするたびに、新しいスレッドを使用することをお勧めします。あなたのイベントハンドルの内部では、変更されたファイルが名前を変更する必要があるかどうかをチェックします。 このようにすると、無限ループを避けることができます。これは、イベント処理コードが何らかの理由で終了するためです。

+0

新しいスレッド?スレッドは多くのシステムメモリを占有しますが、必要以上に多くのスレッドを使用するのではなく、特に**推奨されています。真剣に、これをしないでください、それはとにかくそれを修正しません。 – ThePyroEagle

関連する問題