java 如何在 FileWacther 中查看多个硬盘分区

how to watch multiple hard disk partitions in FileWacther in java

我正在使用 FileWatcher 监视整个硬盘分区,在我的例子中是 D 驱动器,例如:D:/ 代码在我提供的一条路径下运行良好,我只想监视其他硬盘分区像 C:,D: 和 E: 我怎样才能实现这是代码

public class FileWatcher {
    private final WatchService watcher;
    private final Map<WatchKey, Path> keys;
    static Logger log = LoggerFactory.getLogger(GitCloneRepo.class);

    /**
     * Creates a WatchService and registers the given directory
     */
    FileWatcher(Path dir) throws IOException {
        this.watcher = FileSystems.getDefault().newWatchService();
        this.keys = new HashMap<WatchKey, Path>();

        walkAndRegisterDirectories(dir);
    }

    /**
     * Register the given directory with the WatchService; This function will be called by FileVisitor
     */
    private void registerDirectory(Path dir) throws IOException
    {
        WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
        keys.put(key, dir);
    }

    /**
     * Register the given directory, and all its sub-directories, with the WatchService.
     */
    private void walkAndRegisterDirectories(final Path start) throws IOException {
        // register directory and sub-directories
        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                registerDirectory(dir);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                if (exc instanceof AccessDeniedException) {
                    return FileVisitResult.SKIP_SUBTREE;
                }

                return super.visitFileFailed(file, exc);
            }
        });
    }

    /**
     * Process all events for keys queued to the watcher
     */
    void processEvents() {
        for (;;) {

            // wait for key to be signalled
            WatchKey key;
            try {
                key = watcher.take();
            } catch (InterruptedException x) {
                log.error("InterruptedException ",x);
                return;
            }

            Path dir = keys.get(key);
            if (dir == null) {
                log.warn("WatchKey not recognized!!");
                continue;
            }

            for (WatchEvent<?> event : key.pollEvents()) {
                @SuppressWarnings("rawtypes")
                WatchEvent.Kind kind = event.kind();

                // Context for directory entry event is the file name of entry
                @SuppressWarnings("unchecked")
                Path name = ((WatchEvent<Path>)event).context();
                Path child = dir.resolve(name);
                log.info("watching files");
                // print out event
                if (kind == ENTRY_MODIFY) {
                log.info("event.kind().name() {}: child {}", event.kind().name(), child);
                log.info("child {} ends with docx? {} ",child,child.endsWith(".docx"));
                String c= child.toString();
                log.info("**child {}***c.endsWith(.docx)"
                        + ""
                        + " {}",c,c.endsWith(".docx"));
                }
                // if directory is created, and watching recursively, then register it and its sub-directories
                if (kind == ENTRY_CREATE) {
                    try {
                        if (Files.isDirectory(child)) {
                            walkAndRegisterDirectories(child);
                        }
                    } catch (IOException x) {
                        // do something useful
                    }
                }
            }

            // reset key and remove from set if directory no longer accessible
            boolean valid = key.reset();
            if (!valid) {
                keys.remove(key);

                // all directories are inaccessible
                if (keys.isEmpty()) {
                    break;
                }
            }
        }
    }


 //working code
    public static void main(String[] args) throws IOException {
        try{
        Path dir = Paths.get("D:");
        FileWatcher fileWatcher=new FileWatcher(dir);
        fileWatcher.processEvents();
        }

        catch (AccessDeniedException xx) {
            log.error("AccessDeniedException  ",xx);
        }
         catch (FileSystemException x) {
            log.error("exception",x);
        }
        }

}

我看了这个问题,但似乎没有解决我的问题

您的 processEvents 方法进入无限循环并且不会 return 直到线程被中断或路径消失,这意味着 processEvents 之后的任何代码都不会执行直到完成。如果你想让你的 main 方法启动多个观察者,你需要从其他线程调用 processEvents,例如Java 8:

// Create watchers
List<FileWatcher> watchers = new ArrayList<>();
try{
    watchers.add(new FileWatcher(Paths.get("D:")));
    watchers.add(new FileWatcher(Paths.get("E:")));
} catch (AccessDeniedException xx) {
    log.error("AccessDeniedException  ",xx);
} catch (FileSystemException x) {
    log.error("exception",x);
}

// Create and start threads
List<Thread> threads = watchers.stream()
        .map(w -> new Thread(w::processEvents))
        .peek(Thread::start)
        .collect(Collectors.toList());

与Java 7:

// Create watchers
List<FileWatcher> watchers = new ArrayList<>();
try{
    watchers.add(new FileWatcher(Paths.get("D:")));
    watchers.add(new FileWatcher(Paths.get("E:")));
} catch (AccessDeniedException xx) {
    log.error("AccessDeniedException  ",xx);
} catch (FileSystemException x) {
    log.error("exception",x);
}

// Create and start threads
List<Thread> threads = new ArrayList<>();
for (FileWatcher watcher : watchers) {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            watcher.processEvents();
        }
    });
    thread.start();
    threads.add(thread);
}