我希望在文件夹中覆盖文件时收到通知。例如:我在文件夹中有一个A.JSON文件。当我在同一路径中覆盖同一个文件(A.JSON)时,我想收到通知。
我已根据以下链接尝试了WatchService示例。
https://kodejava.org/how-to-monitor-file-or-directory-changes/
// I kept a file called A.JSON in this path
Path path = FileSystems.getDefault().getPath("/Users/XYZ/MyProjectWorkspace/MyTestProject/src");
try {
Boolean isFolder = (Boolean) Files.getAttribute(path,
"basic:isDirectory", NOFOLLOW_LINKS);
if (!isFolder) {
throw new IllegalArgumentException("Path: " + path + " is not a folder");
}
} catch (IOException ioe) {
// Folder does not exists
ioe.printStackTrace();
}
System.out.println("Watching path: " + path);
// We obtain the file system of the Path
FileSystem fs = path.getFileSystem ();
// We create the new WatchService using the new try() block
try(WatchService service = fs.newWatchService()) {
// We register the path to the service
// We watch for creation events
path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
// Start the infinite polling loop
WatchKey key = null;
while(true) {
key = service.take();
// Dequeueing events
Kind<?> kind = null;
for(WatchEvent<?> watchEvent : key.pollEvents()) {
/*final Path changed = (Path) watchEvent.context();
System.out.println(changed);
if (changed.endsWith("A.json")) {
System.out.println("My file has changed");
}
*/
// Get the type of the event
kind = watchEvent.kind();
if (OVERFLOW == kind) {
continue; //loop
} else if (ENTRY_CREATE == kind) {
// A new Path was created
//Path newPath = ((WatchEvent<Path>) watchEvent).context();
// Output
//System.out.println("New path created: " + newPath);
System.out.println("New path created");
} else if (ENTRY_MODIFY == kind) {
// A new Path was created
//Path newPath = ((WatchEvent<Path>) watchEvent).context();
// Output
//System.out.println("New path created: " + newPath);
System.out.println("Modified");
}
}
if(!key.reset()) {
break; //loop
}
}
} catch(IOException ioe) {
ioe.printStackTrace();
} catch(InterruptedException ie) {
ie.printStackTrace();
}
在新文件夹创建或修改等时有效。但是,我希望在文件夹中覆盖同一文件时收到通知。
请告诉我如何解决这个问题?
答案 0 :(得分:0)
监视服务仅查找该目录中的更改。如果您在目录中创建一个文件夹,您将被告知该文件夹的创建。如果您在该新文件夹中创建文件,系统可能会通知您已修改监视目录中的文件夹;您不会被告知在监视目录中的文件夹内添加,修改或删除的文件或文件夹。为此,您还需要查看这些子文件夹。
我将if
语句替换为以下语句:
if (kind == ENTRY_CREATE || kind == ENTRY_MODIFY || kind == ENTRY_DELETE) {
Path newPath = ((WatchEvent<Path>) watchEvent).context();
System.out.println(kind + ": "+newPath+" ");
}
然后我运行代码,创建,修改和删除&#34; A.json&#34;文件在监视目录中。然后我创建了一个&#34;子文件夹&#34;和&#34;子文件夹&#34;在其中,我创建,修改和删除了#34; A.json&#34;每个。我收到了这个输出:
观察路径:/ Users / aneufeld / workspaces / olan / StackOverflow / src / stackoverflow
ENTRY_CREATE:A.json
ENTRY_MODIFY:A.json
ENTRY_DELETE:A.json
ENTRY_CREATE:子文件夹
ENTRY_MODIFY:子文件夹
ENTRY_MODIFY:子文件夹
ENTRY_MODIFY:子文件夹
ENTRY_DELETE:子文件夹
如您所见,监视服务仅在监视目录中正确报告创建,修改和删除。当添加或移除文件夹内的条目时,可以将监视目录中的文件夹标记为已修改,但是没有给出关于提供的修改的指示。子子文件夹内的更改完全无声。
要从起始路径中观看所有子文件夹,而不是
path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
你可以使用:
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
dir.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
return FileVisitResult.CONTINUE;
}
});
这只会注册以path
为根的已存在的文件夹。如果创建了新文件夹,您只会收到ENTRY_CREATE
个事件。您必须确定该条目是一个目录,然后继续注册它。您可能必须查看ENTRY_DELETE
事件,并在删除后从监视服务取消注册路径。锻炼留给学生。