riggedCoinflip
riggedCoinflip

Reputation: 485

file.listFiles() does not list recently created file

I have a component that should do something every time a file in the watched directory is created,updated or deleted.
For the sake of simplicity, lets say it prints the file names to Sysout.

@Component
public class MyComponent {
    @Autowired
    MyComponentWatcher myComponentWatcher

    @PostConstruct
    public void init(){
        myComponentWatcher.registerWatchService();
    }
}

@Component
public class MyComponentWatcher {
    @Value("${somePath}")
    private String myPath;

    private File myDir;

    @PostConstruct
    public void init() {
        this.myDir = new File(myPath);
    }

    @Async
    public void registerWatchService() throws IOException, InterruptedException {
        WatchService watchService
                = FileSystems.getDefault().newWatchService();

        Path path = myDir.toPath();

        path.register(
                watchService,
                StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE,
                StandardWatchEventKinds.ENTRY_MODIFY);

        WatchKey key;
        while ((key = watchService.take()) != null) {
            for (WatchEvent<?> event : key.pollEvents()) {
                System.out.println(
                        "Event kind:" + event.kind()
                                + ". File affected: " + event.context() + ".");
            }
            key.reset();

            File[] files = myDir.listFiles();
            System.out.println(files); //!!!
        }
    }
}

GIVEN my dir contains 1 file
WHEN I create another file
THEN System.out.println(files); returns the old and the new file
-> I only get the old file!

I wrote a test case that uses Files.write(filePath, fileContent.getBytes(), CREATE_NEW); to create the test file and

    @AfterEach
    void tearDown() {
        File toDelete = new File(filePath.toString());
        toDelete.delete();
    }

to delete the test file after the test.

In total the watcher triggers 3 times with the following lists of events:

  1. [ENTRY_CREATE, ENTRY_MODIFY]
  2. [ENTRY_MODIFY]
  3. [ENTRY_MODIFY]
  4. [ENTRY_DELETE]

Upvotes: 1

Views: 224

Answers (1)

Ashish Ratan
Ashish Ratan

Reputation: 2870

Your code is working fine as expected and written. to achieve your output, you need to recreate the object for File class.

// we are creating the object just after the constructor
@PostConstruct
public void init() {
    this.myDir = new File(myPath);
}

but then you modified your path but not the actual instance variable:

please change your code File[] files = new File(myPath).listFiles();

Upvotes: 1

Related Questions