当前位置: 首页 > 知识库问答 >
问题:

如何在Java中的FileWacther中观看多个硬盘分区

章昆琦
2023-03-14

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

}

我看了这个问题但我似乎没有解决我的问题如何实现文件观察者观看多个目录

共有1个答案

秋光熙
2023-03-14

您的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);
}
 类似资料:
  • 问题内容: 有没有办法使用以下方法订阅多个对象上的事件 例如 问题答案: 从AngularJS 1.3开始,有一个新方法称为观察一组表达式。

  • 4.a. 块设备 (Block Device) 简介 各色块设备 We'll take a good look at disk-oriented aspects of Gentoo Linux and Linux in general, 包括 Linux 的文件系统, 分区, 以及块设备. 随后, 一旦您已经里里外外明白了磁盘与文件系统这些东西, 您就可以开始跟随我们的向导开始为您的 Gentoo

  • 问题内容: 本文介绍如何在Java VisualVM中查看内存分配堆栈跟踪:http : //rejeev.blogspot.de/2009/04/analyzing-memory-leak-in- java.html 简而言之,请在Java VisualVM选项中定义一个自定义预设,然后选中 “ 内存设置”选项卡中的 “记录分配堆栈跟踪”复选框 。 现在,当我选择该自定义预设并开始内存分析时,我

  • 我有一些字符串,我想替换其中的一些字符。一切都很好,直到字符串没有两个或更多相同的字符,程序只是替换了第一个字符,而我无法更改第二个字符。 下面是对这段代码的解释:用户从一开始程序就有一个等于10的分数。userLetter它只是一个字符,它将从用户那里得到一些字母,然后如果语句检查movieTitle变量的字符是否等于用户刚刚输入的字符,如果是,charIndex将有它的位置(但它只包含第一个索

  • 硬盘回收站用于存放用户删除的硬盘文件。 回收站中主机和硬盘文件默认保存3天,如有误删除的主机或硬盘文件需要在3天内进行恢复操作,可以将其恢复到原来位置,超过3天后,文件将被彻底删除。 入口:在云管平台单击左上角导航菜单,在弹出的左侧菜单栏中单击 “主机/回收站/硬盘” 菜单项,进入硬盘回收站列表。 清除 当确定回收站中的硬盘文件无用后,可使用清除功能立即彻底删除文件。 清除单个硬盘 单击 “清除”

  • 硬盘是虚拟机的存储文件。 硬盘是虚拟机的存储文件。硬盘根据位置可分为本地硬盘和云硬盘,其中要求本地硬盘与虚拟机处于同一宿主机。本地硬盘不支持在硬盘列表中新建、挂载和卸载。要求云硬盘与虚拟机处于相同可用区,云硬盘支持新建、挂载、卸载、扩容、删除等操作。 入口:在云管平台单击左上角导航菜单,在弹出的左侧菜单栏中单击 “主机/存储/硬盘” 菜单项,进入硬盘页面。 新建硬盘 该功能用于创建硬盘,新创建的硬