Java NIO:观察文件树时在重命名的文件夹中创建文件时出现问题

Java NIO: Problem creating files in a renamed folder when observing a file tree

提问人:paul 提问时间:8/17/2023 更新时间:8/17/2023 访问量:34

问:

我目前正在使用 Java NIO 进行一个项目,该项目应该只是观察位于特定目录中的所有子目录和文件。当发生 Delete 或 Create 事件时,应将其打印到控制台。我实现了这一点并发现了一个问题,经过几个小时的尝试,我无法解决。

因此,在各种子文件夹中创建和删除文件夹和文件效果很好,但是如果您重命名文件夹并尝试在新重命名的文件夹中创建文件,则会从 Java NIO 获得错误的值。我将尝试用一个例子来解释它:

Context: pre_rename
Kind: ENTRY_DELETE
Watchable: C:\niotest
Dir: C:\niotest
Context Path: C:\niotest\pre_rename
-------------------------------------
Context: post_rename
Kind: ENTRY_CREATE
Watchable: C:\niotest
Dir: C:\niotest
Context Path: C:\niotest\post_rename
C:\niotest registered
-------------------------------------
Context: testfile.txt
Kind: ENTRY_CREATE
Watchable: C:\niotest\pre_rename
Dir: C:\niotest\pre_rename
Context Path: C:\niotest\pre_rename\testfile.txt
C:\niotest\pre_rename registered
-------------------------------------

这是我将文件夹“pre_rename”重命名为“post_rename”(删除后跟创建)并在“post_rename”中创建文件“testfile.txt”后得到的输出。正如你所看到的,蔚来给出的路径在最后一节中仍然pre_rename而不是post_rename。你们能帮我解决这个问题吗? 在下文中,我将分享我的代码:

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class Main {
    public static void main(String[] args) {
        try(WatchService watchService = FileSystems.getDefault().newWatchService()){
            Path directory = Path.of("C:\\niotest");
            registerSubdirectories(directory, watchService);

            WatchKey key;
            while((key = watchService.take()) != null){
                for(WatchEvent event : key.pollEvents()){
                    System.out.println("Context: " + event.context());
                    System.out.println("Kind: " + event.kind());
                    System.out.println("Watchable: " + key.watchable());
                    Path dir = (Path) key.watchable();
                    System.out.println("Dir: " + dir);
                    Path contextPath = dir.resolve((Path) event.context());
                    System.out.println("Context Path: " + contextPath);
                    if(event.kind() == StandardWatchEventKinds.ENTRY_CREATE){
                        registerSubdirectories(directory, watchService);
                        System.out.println(dir + " registered");
                    }
                    System.out.println("-------------------------------------");
                }
                key.reset();
            }
        }
        catch (IOException e){
            e.printStackTrace();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private static void registerSubdirectories(Path start, WatchService watchService) throws IOException {
        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attributes) throws IOException {
                dir.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
                //System.out.println(dir);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

我尝试使用 key.close() 和 reset(),但没有一个真正起作用。我还尝试在registerSubdirectories方法中更改次要想法。

对我来说,看起来 NIO 正在观察文件夹的旧名称和新名称(在我的情况下是 pre 和 post_rename),因此可能更喜欢返回旧路径,但我还没有找到清除一个特定路径的方法,我也不是 100% 确定这是否是问题所在。

如果缺少任何信息或某些内容,请告诉我。 期待您的回复,提前致谢!

NIO Java-IO 监视服务

评论

0赞 VGR 8/17/2023
在 registerSubdirectories 方法中,您在不可变的 Path 对象上注册了监视事件。监视事件与监视的 Path 对象相关联。我认为为了看到更新的路径,您必须在新“创建”的目录上重新注册您的 WatchService,然后从“已删除”目录中取消注册。C:\niotest\pre_rename

答: 暂无答案