I've tried to copy&paste a very small file into a folder which is observed by a watch service. The first time works great, but on all following copy&paste actions, i get an exception that another process handles the file already. With experiments I've found out that my service is informed when Windows creates the file and not when its content is copied. If I lock the file, Windows isn't able to copy any data and the file is empty. On the other hand, if I move the file into the directory, everything works fine.
Is that a bug from Windows? I wasn't able to test it on a mac or Linux workstation. Or maybe it was just me being incapable. Any help is appreciated.
My code looks like the following:
try (WatchService watchService = importPath.getFileSystem().newWatchService()) {
importPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
handleExistingFiles();
try {
do {
WatchKey watchKey = watchService.take();
if (!watchKey.isValid()) {
continue;
}
boolean hasCreationEvents = false;
for (WatchEvent<?> event : watchKey.pollEvents()) {
hasCreationEvents |= event.kind().equals(StandardWatchEventKinds.ENTRY_CREATE);
}
watchKey.reset();
if (hasCreationEvents) {
handleNewFiles();
}
}
while (!Thread.currentThread().isInterrupted());
}
catch (InterruptedException ignoredEx) {
Thread.currentThread().interrupt();
}
}
The copy operation is not always atomic.
With atomic copy (or move) you will get a single ENTRY_CREATE event and the file referenced by the event will be complete and available for reading.
If the copy is not atomic, you will receive an ENTRY_CREATE event when the file is created and then you will receive one or more ENTRY_MODIFY events while the file is being written by the copy operation.
There is no easy way to determine when the copy operation has finished writing to a file and released it. Depending on the OS and file system you could get FileNotFoundException when trying to open a file for reading while it is locked by the copy operation or you could successfully open a file but you will get partial contents when you actually read it.
You will have to implement some heuristics like trying to read a file immediately after ENTRY_CREATE and rescheduling the reading for some later time if the initial reading failed.
来源:https://stackoverflow.com/questions/22956262/java-watchservice-gets-informed-before-content-is-copied