我正在使用WatchService API来监视目录,并在用户开始将文件复制到目录中时获取ENTRY_CREATE事件.我正在使用的文件可能很大,我想知道副本何时完成.是否有任何内置的java API可用于实现此目的,或者我最好只是跟踪创建的文件的大小并在大小停止增长时开始处理?
编辑:这是我的示例代码:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
哪个产生这个输出:
Monitoring /Users/ericcobb/Develop/watch
Event .DS_Store, type ENTRY_MODIFY
Event 7795dab5-71b1-4b78-952f-7e15a2f39801-84f3e5daeca9435aa886fbebf7f8bd61_4.mp4, type ENTRY_CREATE
Run Code Online (Sandbox Code Playgroud)
Jef*_*rey 10
创建条目后,您将获得一个ENTRY_CREATE事件.对于每次后续修改,您都将获得一个ENTRY_MODIFY活动.复制完成后,您将收到通知ENTRY_MODIFY.
确保没有其他进程再写入文件的唯一有效选项是成功获得文件的写锁。虽然有点笨拙,但您可以为此目的使用FileChannel和FileLock
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
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用ch.lock()阻塞调用获取锁。但是由于 ENTRY_MODIFY 事件在写入文件时会不断生成,因此您也可以使用 tryLock 并等待下一个事件。