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

38 Views Asked by At

I am currently working on a project with Java NIO which should simply observe all subdirectories and files located in a specific directory. When a Delete or Create event happens it should be printed to the console. I implemented this and discovered a problem, which I couldnt solve after hours of trying.

So creating and deleting folders and files in all kinds of subfolders works well but if you rename a folder and try to create a file in that newly renamed folder you get wrong values from Java NIO. I will try to explain it in an example:

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
-------------------------------------

This is the output I get from renaming the folder "pre_rename" to "post_rename" (Delete followed by Create) and after that creating the file "testfile.txt" in "post_rename". As you can see, the path given by NIO still contatins pre_rename instead of post_rename in the last section. Can you guys help me how to fix this? In the following I will share my code:

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;
            }
        });
    }
}

I trying playing around with key.close() and reset() but none of it really worked. I also tried to change minor thinks in the registerSubdirectories method.

To me it looks like NIO is observing the old and the new name of the folder (in my case pre and post_rename) and therefore probably just prefers to return the old path but I havenot found a way to clear one specific path and I am not 100% sure if that is even the problem either.

If any infos or something are missing please let me know. Looking forward to your replies, thanks in advance!

0

There are 0 best solutions below