Created for a console application that will be run in the background on a linux system, giving me a nice way to gracefully shut it down by simply deleting a file (which can be done via script/etc.)
public class BlockOnRunFile {
private File watchedFile;
private Path path;
private WatchService watcher;
public void end() {
watchedFile.delete();
}
public BlockOnRunFile(String runFilePath) throws IOException {
watcher = FileSystems.getDefault().newWatchService();
path = FileSystems.getDefault().getPath(
runFilePath.substring(0, runFilePath.lastIndexOf(FileSystems
.getDefault().getSeparator())));
watchedFile = new File(runFilePath);
watchedFile.createNewFile();
}
public void block() {
try {
WatchKey key;
key = path.register(watcher, StandardWatchEventKinds.ENTRY_DELETE);
// stall until the game is supposed to end
// reset key to allow new events to be detected
while (key.reset()) {
// key = watcher.take();
try {
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
Common.log.logMessage("File watcher overflow",
LogLevel.INFO);
if (!watchedFile.exists()) {
// do nothing
;
}
break;
}
if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path filename = ev.context();
if (filename
.toAbsolutePath()
.toString()
.equals(watchedFile.getAbsolutePath()
.toString())) {
watcher.close();
break;
}
}
}
Thread.sleep(1000); // prevent CPU burn, worst-case: 1 second delay on shutdown
} catch (Exception e) {
watcher.close();
Common.log.logMessage(e, LogLevel.INFO);
continue;
}
}// end while loop
} catch (IOException e1) {
Common.log.logMessage(e1, LogLevel.ERROR);
}
}
}
It works, and I don't expect there to be any large amount of file operations in the directory where the file exists, but I would still like to know of any possible issues (I intend to automate it via some scripts/crontab and make sure it's robust enough)