WatchService
from JDK7 to monitor filesystem activity. I also wanted to demonstrate using it with an Executor
.As part of the process, I needed a graceful way to exit the program when the program completed. I thought that I would simply Google a solution, but I did not find one that met my needs.
So here is the use case I would like to have a WatchService running in its own thread and monitoring the filesystem. After a time period, I would like the service to shutdown gracefully.
I decided to use A
ScheduledExecutorService
which would start the WatchService using a Callable<V>
, and another Runnable
which was scheduled to shutdown the WatchService and the ScheduledExecutorService.So here is how I did it.
WatchServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | /* * Copyright 2012 Blue Lotus Software, LLC. * Copyright 2012 John Yeary. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bluelotussoftware.module7.watch; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import static java.nio.file.StandardWatchEventKinds.*; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.Arrays; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * * @author John Yeary * @version 1.0 */ public class WatchServiceImpl { public static void main(String... args) throws IOException { if (args.length == 0 ) { System.err.println( "You need to pass at least one argument." ); System.exit(- 1 ); } Path target; if (args.length > 1 ) { target = Paths.get(args[ 0 ], Arrays.copyOfRange(args, 1 , args.length - 1 )); } else { target = Paths.get(args[ 0 ]); } WatchService watchService = FileSystems.getDefault().newWatchService(); target.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY, OVERFLOW); runWatchService(watchService, 60 , TimeUnit.SECONDS); } public static void runWatchService( final WatchService service, final long timeout, final TimeUnit timeUnit) { final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool( 2 ); final Future< void > future = scheduledExecutorService.submit( new Callable< void >() { @Override public Void call() throws Exception { System.out.println( "Running WatchService..." ); WatchKey watchKey; try { watchKey = service.take(); } catch (InterruptedException ex) { return null ; } while (!Thread.interrupted()) { for (WatchEvent<?> event : watchKey.pollEvents()) { WatchEvent.Kind<?> kind = event.kind(); WatchEvent<path> watchEvent = (WatchEvent<path>) event; Path filename = watchEvent.context(); System.out.println( "File Name: " + filename); switch (kind.name()) { case "ENTRY_CREATE" : { System.out.println(filename + " created!" ); break ; } case "ENTRY_MODIFY" : { System.out.println(filename + " modified!" ); break ; } case "ENTRY_DELETE" : { System.out.println(filename + " deleted!" ); break ; } case "OVERFLOW" : { System.out.println( "Events may have been lost" ); break ; } } } watchKey.reset(); } return null ; } }); // Schedule another job to cancel our currenly running job and shutdown Executor. scheduledExecutorService.schedule( new Runnable() { @Override public void run() { future.cancel( true ); scheduledExecutorService.shutdown(); System.out.println( "WatchService Shutdown." ); } }, timeout, timeUnit); } } |
0 comments :
Post a Comment