我注册了一个Java WatchService来检查文件是否被修改。如果您使用Sublime或Notepad等文件查看器,一切正常。但是,如果我尝试在服务器上使用bash文件查看器(如vim)编辑我的文件(在本例中是一个config.properties文件),则会永久执行while循环,从而在系统上施加高负载并输出以下内容:
2016-11-28 15:17:38.031 [INFO ] [Thread-7] PropertyReader pollPropertyFileModification - while (true)
2016-11-28 15:17:38.031 [INFO ] [Thread-7] PropertyReader pollPropertyFileModification - while (true)
2016-11-28 15:17:38.031 [INFO ] [Thread-7] PropertyReader pollPropertyFileModification - while (true)
这是一个错误还是我错误地使用了WatchService?这是我的代码:
private void pollPropertyFileModification() {
logger.debug("entry");
final Path path = Paths.get(System.getProperty(Constants.CONFIG_FILE));
logger.debug("Filename: {}", path.getFileName());
logger.debug("Parent Path: {}", path.getParent());
try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
path.getParent().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
final WatchKey watchKey = watchService.take();
// final WatchKey watchKey = watchService.poll(10, TimeUnit.SECONDS);
while (true) {
logger.info("while (true)");
for (WatchEvent<?> event : watchKey.pollEvents()) {
// we only register "ENTRY_MODIFY" so the context is always a Path.
final Path filename = (Path) event.context();
logger.info("Filename: {}", filename);
if (filename.endsWith(path.getFileName())) {
logger.info("{} has changed", filename);
}
}
// reset the key
if (!watchKey.reset()) {
logger.info("Key has been unregistered");
break;
}
}
} catch (IOException ex) {
logger.error("IOException", ex);
} catch (InterruptedException ex) {
logger.error("InterruptedException", ex);
}
logger.debug("exit");
}
更新
正如@Ironcache指出的那样,watchService.take();
调用位置错误,必须放在循环中
private void pollPropertyFileModification() {
logger.debug("entry");
final Path path = Paths.get(System.getProperty(Constants.CONFIG_FILE));
logger.debug("Filename: {}", path.getFileName());
logger.debug("Parent Path: {}", path.getParent());
try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
path.getParent().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
logger.info("while (true)");
final WatchKey watchKey = watchService.take();
for (WatchEvent<?> event : watchKey.pollEvents()) {
// we only register "ENTRY_MODIFY" so the context is always a Path.
final Path filename = (Path) event.context();
logger.info("Filename: {}", filename);
if (filename.endsWith(path.getFileName())) {
logger.info("{} has changed", filename);
}
}
// reset the key
if (!watchKey.reset()) {
logger.info("Key has been unregistered");
break;
}
}
} catch (IOException ex) {
logger.error("IOException", ex);
} catch (InterruptedException ex) {
logger.error("InterruptedException", ex);
}
logger.debug("exit");
}