如何观察完整的文件系统中Java的变化?

如何观察完整的文件系统中Java的变化?,java,recursion,filesystems,watch,watchservice,Java,Recursion,Filesystems,Watch,Watchservice,问题描述 我想看一个完整的文件系统的变化。我说的是递归地观察目录中的更改。因此,在监视一个目录或整个文件系统时,也需要捕获子目录中的所有更改。应用程序需要能够通过收到通知来跟踪所有更改 Java的WatchService不适用 Java已经有了WatchService特性,它允许您监视目录的更改。然而,问题是,据我所知,这不是一个递归过程,因此您不能使用它来监视文件系统根目录中的所有更改 显式监视所有子目录 我想到的一个解决方案是显式注册指定根目录中的每个目录。然而,问题是,在一个拥有超过一百万

问题描述 我想看一个完整的文件系统的变化。我说的是递归地观察目录中的更改。因此,在监视一个目录或整个文件系统时,也需要捕获子目录中的所有更改。应用程序需要能够通过收到通知来跟踪所有更改

Java的WatchService不适用 Java已经有了WatchService特性,它允许您监视目录的更改。然而,问题是,据我所知,这不是一个递归过程,因此您不能使用它来监视文件系统根目录中的所有更改

显式监视所有子目录 我想到的一个解决方案是显式注册指定根目录中的每个目录。然而,问题是,在一个拥有超过一百万个子目录的系统上,遍历和注册这些目录是非常昂贵的资源。这是因为系统首先需要递归地遍历整个文件系统,以便只注册所有目录。如果在不使应用程序崩溃的情况下,此功能对性能的影响太大

逻辑解决方案 我假设,当文件系统中的任何内容发生更改时,操作系统会触发/调用某种事件,而应用程序能够监听这些事件。然而,我还没有找到这样的东西。这将允许应用程序侦听所有更改,而无需显式注册所有子目录。因此,这种方法对性能的影响最小

问题: 在Java中,监视整个文件系统或递归地监视目录是可能的吗?这是如何实现的?

是监视目录或树以查看文件更改的示例请查找示例


即使您可以筛选您不想观看的目录

问题也应分为几个部分:

如何在某些操作系统上跨磁盘跟踪文件事件 如何在Java中使用这种机制 第一个问题的答案是,方法不同。在Windows上存在允许您执行此操作的Windows API函数,.NET Framework中著名的FileSystemWatcher类是围绕此API函数集的一种包装器。windows上更健壮的方法是创建或使用预先创建的文件系统筛选器驱动程序。在Linux上存在。在MacOS X上,有几种方法,在这个主题上有一个问题,没有一种是通用的或总是可用的。 此外,除了文件系统过滤器驱动程序之外,所有方法都只适用于在事件发生后收到通知,但它们不允许您拦截和拒绝请求。好吧,我可能会弄错


至于第二个问题,似乎没有一个通用的解决方案可以涵盖我上面提到的所有或大部分变体。您需要首先为每个操作系统选择机制,然后找到一些Java包装器来使用这些机制

您提到的副本的可能副本似乎只指向WatchService。这个问题是关于监视一个文件系统的。通常,所提到的监视服务只是为了涵盖一个不合适的方法。我想说,对于一个有数百万子目录的目录来说,这可能是不可能的。至少在Linux上不是这样,在Linux上,这种监视是由inotify完成的,它不是递归的。这个方法使用我在问题中提到的方法。它显式地注册所有子目录,正如您在registerAll方法中看到的那样。对于一个拥有超过一百万个目录的文件系统来说,这不是一个选项。啊..那么这是一个复杂的情况吗?你不能创建一个缓存并在单独的线程中更新该缓存,比如说每30分钟一次吗?你的意思是,缓存文件系统中的所有文件,并在30分钟后再次将缓存与文件系统进行比较?不,这需要应用程序每30分钟重新检查一次整个文件系统。在HDD存储设备上一次检查所有内容可能需要12个小时。您的答案是仅链接的答案,对于堆栈溢出来说,这不是正确的答案。你应该在答案中解释链接内容的要点。链接可能会断开。至少你应该提到链接链接的内容。这个答案与Mohan Sharma发布的Sheetal类似。这个例子的问题是,应用程序正在遍历文件系统上的所有目录,并显式地注册它们。这将需要应用程序注册超过一百万个目录,这不是一个合适的解决方案。这种方法对性能的影响将是巨大的,使应用程序无法使用。