有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我使用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);
        }
        }

}

我看了这个问题,但我似乎没有解决我的问题 How to implement file watcher to Watch multiple directories


共 (1) 个答案

  1. # 1 楼答案

    你的processEvents方法进入一个无限循环,直到线程被中断或路径消失后才会返回,这意味着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);
    }