如何判断文件何时"完成"复制到监视目录?

eri*_*ric 23 java file path

我正在使用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.

  • 我认为@PashaTurok正试图找出副本何时完成.正如您在答案中所说,当副本正在进行和完成时,您会收到"ENTRY_MODIFY"事件.那么你怎么知道你有最后一个`ENTRY_MODIFY`?你有一段时间思考,如果你没有得到任何进一步的'ENTRY_MODIFY`事件,你可以考虑复制完成吗?似乎FWP,但这可能是唯一的方法. (6认同)

Ger*_*cke 5

确保没有其他进程再写入文件的唯一有效选项是成功获得文件的写锁。虽然有点笨拙,但您可以为此目的使用FileChannelFileLock

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 并等待下一个事件。