大変お久しぶりです。
先日はディレクトリの監視対象の登録について見ましたが、今回は登録したディレクトリの監視対象にイベントが発生した時の処理について見てみましょう。
ディレクトリの監視の登録をすると、ディレクトリの監視が開始されます。
ディレクトリの監視は、発生しているイベントを取得し、イベントに応じた処理を行うという形式で行います。
通常は、イベントを取得し続けるために、無限ループを使用します。
WatchServiceインターフェースから、発生しているイベントをまとめたWatchKeyオブジェクトを取得するには、3種類の方法があります。
takeメソッドはイベントが発生するまでブロックするメソッドです。
イベント発生までブロックするため、InterruptedException例外がスローされることがあります。
takeメソッド以外に引数なしのpollメソッドと、ひきすうとして待ち時間を指定するpollメソッドがあります。
pollメソッドはイベントが発生していない場合、nullを返します。
待ち時間を指定するpollメソッドは、イベントの発生を指定した時間だけ待ちますが、それでもイベントが発生しないばあはnullを返します。
待ち時間を指定する場合もInterruptedException例外がスローされることがあります。
WatchKeyインターフェースには、発生したイベントをリスト形式で返すpollEventsメソッドが定義されています。
イベントはWatchEventインターフェースで表されます。
そこで、拡張for文を使用して、個々のイベントに対する処理を記述していきます。
イベントの種類はWatchEventインターフェースのkindメソッドで取得できます。
kindメソッドの返り値の型は、監視の登録時に使用したWatchEvent.Kindクラスです。
こちらも実際に使用されるのはStandardWatchEventKindsクラスです。
イベントの処理を行った後、WatchKeyインターフェースのresetメソッドをコールします。
resetメソッドをコールすることで、次のイベントを扱うことが可能になります。
では、ディレクトリの監視を行ってみましょう。
// ディレクトリの監視例while(true) { try{ // 現在発生しているキーを取得 WatchKey key = watchService.take();
// キーからイベントを取得 for(WatchEvent<?> event : key.pollEvents()) { if(event.kend() == StandardWatchEventKinds.OVERFLOW) { // イベントがオーバーフローしていまった場合 key.reset(): continue; } else { // それ以外の場合、 // イベントの種類と対象となるパスを出力 System.out.println(event.kind() + " " + event.context()); }
// キーをリセット if(!key.reset()) { break; } } } catch(InterruptedException ex) { break; }}
// ディレクトリ監視の終了watchService.close();
上記ソースは、無限ループで監視イベントを取得し続けています。
まず、takeメソッドを使用してWatchKeyオブジェクトを取得します。
そして、WatchKeyオブジェクトからWatchKeyオブジェクトを取得しています。
監視の登録時に使用しなかった定数として、OVERFLOWがあります。
これはイベントがオーバーフローを起こし、処理できていないことを示します。
ここでは、WatchKeyインターフェースのresetメソッドをコールして、リセットを行っています。
オーバーフローしているので、あふれてしまったイベントは扱えません。
OVERFLOW以外のイベントの場合、kindメソッドでイベントの種類、contextメソッドでイベントの対象となったパスを出力しています。
ディレクトリの監視を終了させる場合、WatchServiceインターフェースのcloseメソッドをコールします。
今回はディレクトリの監視について見てみました。
いままで煩雑だったファイルに関する大幅の操作がNIO2によって簡易化したのが分かりますね!
次回はJava8で導入されたラムダ式について見ていきたいと思います。
それではまた!
人気ブログランキングへ