我有一个监控目录中任何更改的程序。
这是该计划的输出。
C:\REST API\source\data_id.txt
The new file :data_id.txtEvent :ENTRY_CREATE
C:\REST API\source\New folder
The new file :New folderEvent :ENTRY_CREATE
C:\REST API\source\NhuPhutBanDau-NooPhuocThinh-4549467.doc
The new file :NhuPhutBanDau-NooPhuocThinh-4549467.docEvent :ENTRY_CREATE
我的程序监视根目录C:/REST API/source
是否有任何更改。当我将data_id.txt
文件复制到根目录时,它能够检测新文件,如上面的输出和目录中所示。
在此之后,当我尝试创建文件夹时,它还能够检测到新文件夹并在输出中显示新文件夹目录。
但问题是,当我尝试将文件放入新创建的文件夹时,它再次能够检测到新文件夹C:\REST API\source\New folder
中的更改,该文件夹不是我程序中设置的根目录这是C:\REST API\source
。
我需要程序只检测根目录中的更改。
有人可以指导我吗?
这是我的源代码:
public class fileStatus {
private final WatchService svc = null;
private final HashMap<WatchKey , Path> keyMap = null;
public static void main(String [] args) throws FileNotFoundException, IOException, JSONException, InterruptedException
{
try(WatchService svc = FileSystems.getDefault().newWatchService())
{
Map<WatchKey, Path> keyMap = new HashMap<>();
Path path = Paths.get("C:/REST API/source/");
fileStatus fs = new fileStatus();
fs.registerAll(path,keyMap,svc);
WatchKey wk ;
do
{
wk = svc.take();
Path dir = keyMap.get(wk);
for(WatchEvent<?> event : wk.pollEvents())
{
WatchEvent.Kind<?> type = event.kind();
Path fileName = (Path)event.context();
Path child = path.resolve(fileName);
System.out.println(child);
if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS))
{
if(type == StandardWatchEventKinds.ENTRY_CREATE)
{
registerAll(child,keyMap,svc);
}
}
System.out.println("\nThe new file :"+fileName+ "Event :" +type);
}
}while(wk.reset());
}
catch(IOException e)
{
e.printStackTrace();
}
}
private static void registerAll(Path path, Map<WatchKey, Path> keyMap, WatchService svc) throws IOException
{
Files.walkFileTree(path,new SimpleFileVisitor<Path>()
{
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) throws IOException
{
if(attrs.isDirectory())
{
keyMap.put(path.register(svc, StandardWatchEventKinds.ENTRY_CREATE),path);
}
return FileVisitResult.CONTINUE;
}
});
}
}
答案 0 :(得分:1)
在某些地方,您要注册监控文件创建的路径,这是不必要的。
您可以从main
方法
if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) {
if (type == StandardWatchEventKinds.ENTRY_CREATE) {
registerAll(child, keyMap, svc);
}
}
您不应该使用registerAll
方法执行步行树。所以,而不是这个,
Files.walkFileTree(path,new SimpleFileVisitor<Path>()
{
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) throws IOException
{
if(attrs.isDirectory())
{
keyMap.put(path.register(svc, StandardWatchEventKinds.ENTRY_CREATE),path);
}
return FileVisitResult.CONTINUE;
}
});
请使用:
keyMap.put(path.register(svc, StandardWatchEventKinds.ENTRY_CREATE),path);
上面的代码片段将递归地将根目录的内部文件夹添加到keymap中。这就是你看到意外行为的原因。
希望这有帮助!