Skip to content

Instantly share code, notes, and snippets.

@lasombra
Forked from danielflower/FileWatcher.java
Created April 22, 2017 09:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lasombra/42219d25541aacd77a38f2d928fe09b9 to your computer and use it in GitHub Desktop.
Save lasombra/42219d25541aacd77a38f2d928fe09b9 to your computer and use it in GitHub Desktop.
Watching a single file in java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.*;
public class FileWatcher {
private static final Logger log = LoggerFactory.getLogger(FileWatcher.class);
private Thread thread;
private WatchService watchService;
public interface Callback {
void run() throws Exception;
}
/**
* Starts watching a file and the given path and calls the callback when it is changed.
* A shutdown hook is registered to stop watching. To control this yourself, create an
* instance and use the start/stop methods.
*/
public static void onFileChange(Path file, Callback callback) throws IOException {
FileWatcher fileWatcher = new FileWatcher();
fileWatcher.start(file, callback);
Runtime.getRuntime().addShutdownHook(new Thread(fileWatcher::stop));
}
public void start(Path file, Callback callback) throws IOException {
watchService = FileSystems.getDefault().newWatchService();
Path parent = file.getParent();
parent.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
log.info("Going to watch " + file);
thread = new Thread(() -> {
while (true) {
WatchKey wk = null;
try {
wk = watchService.take();
Thread.sleep(500); // give a chance for duplicate events to pile up
for (WatchEvent<?> event : wk.pollEvents()) {
Path changed = parent.resolve((Path) event.context());
if (Files.exists(changed) && Files.isSameFile(changed, file)) {
log.info("File change event: " + changed);
callback.run();
break;
}
}
} catch (InterruptedException e) {
log.info("Ending my watch");
Thread.currentThread().interrupt();
break;
} catch (Exception e) {
log.error("Error while reloading cert", e);
} finally {
if (wk != null) {
wk.reset();
}
}
}
});
thread.start();
}
public void stop() {
thread.interrupt();
try {
watchService.close();
} catch (IOException e) {
log.info("Error closing watch service", e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment