I'm using the WatchService API to watch a directory, and getting ENTRY_CREATE events when a user starts copying a file into the directory. The files I'm working with can be large, though, and I'd like to know when the copy is finished. Is there any built in java API I can use to accomplish this, or am I best off to just keep track of the created files' size and start processing when the size stops growing?
EDIT: Here is my example code:
package com.example;
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
public class Monitor {
public static void main(String[] args) {
try {
String path = args[0];
System.out.println(String.format( "Monitoring %s", path ));
WatchService watcher = FileSystems.getDefault().newWatchService();
Path watchPath = FileSystems.getDefault().getPath(path);
watchPath.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey key = watcher.take();
for (WatchEvent<?> event: key.pollEvents()) {
Object context = event.context();
System.out.println( String.format( "Event %s, type %s", context, event.kind() ));
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Which Produces this output:
Monitoring /Users/ericcobb/Develop/watch
Event .DS_Store, type ENTRY_MODIFY
Event 7795dab5-71b1-4b78-952f-7e15a2f39801-84f3e5daeca9435aa886fbebf7f8bd61_4.mp4, type ENTRY_CREATE
When an entry is created, you will get an ENTRY_CREATE
event. For every subsequent modification, you will get an ENTRY_MODIFY
event. When copying is completed, you will be notified with an ENTRY_MODIFY
.
The only valid option to ensure, no other process is writing to the file anymore is to successfully obtain a Write lock on the file. Although a bit clumsy, you could use FileChannel and FileLock for that purpose
try(FileChannel ch = FileChannel.open(p, StandardOpenOption.WRITE);
FileLock lock = ch.tryLock()){
if(lock == null) {
//no lock, other process is still writing
} else {
//you got a lock, other process is done writing
}
} catch (IOException e) {
//something else went wrong
}
You could as well obtain a lock using ch.lock()
which is a blocking call. But since ENTRY_MODIFY events are continously generated when the file is being written to, you can as well use tryLock and wait for the next event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With