【问题标题】:How to watch a complete file system for changes in Java?如何观察一个完整的文件系统在 Java 中的变化?
【发布时间】:2016-05-01 23:28:18
【问题描述】:

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

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

明确查看所有子目录
我想到的一个解决方案是在指定的根目录中显式注册每个目录。然而,这样做的问题是,在具有超过一百万个子目录的系统上,遍历和注册这些目录是非常昂贵的资源。这是因为系统需要递归地遍历整个文件系统才能首先注册所有目录。此功能对性能的影响太大了,如果它甚至可以不使应用程序崩溃的话。

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

问题
在 Java 中是否可以查看整个文件系统或递归查看目录,这将如何实现?

【问题讨论】:

  • 您提到的副本似乎只指向WatchService。这个问题是关于一般看文件系统的,提到的WatchService只是为了覆盖一个不合适的方法。
  • 我会说这对于具有数百万个子目录的目录来说可能是不可能的。至少不是在 Linux 上,这种监控是由inotify 完成的,对于reasons given on Quora by the author,这不是递归的

标签: java recursion filesystems watch watchservice


【解决方案1】:

问题应该分成几个:

  1. 如何在特定操作系统上跨磁盘跟踪文件事件
  2. 如何在 Java 中使用这种机制

第一个问题的答案是方法不同。在 Windows 上,存在允许您执行此操作的 Windows API 函数(.NET Framework 中著名的 FileSystemWatcher 类是该 API 函数集的一种包装器)。 Windows 上更强大的方法是创建或使用预先创建的文件系统过滤器驱动程序。在 Linux 上存在 inotify。在 MacOS X 上存在几种方法(在某个地方有关于这个主题的问题),它们都不是通用的或始终可用的。 此外,除了文件系统过滤器驱动程序之外的所有方法都只适用于在事件发生后收到通知,但它们不会让您拦截和拒绝请求(AFAIK,我在这里可能会弄错)。

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

【讨论】:

    【解决方案2】:

    Here 是监视目录(或树)以更改文件的示例

    【讨论】:

    • 此方法使用我在问题中提到的方法。正如您在registerAll() 方法中所见,它正在显式注册所有子目录。对于具有超过一百万个目录的文件系统,这不是一个选择。
    • 啊..那么情况很复杂?您不能创建一个缓存并在单独的线程中更新该缓存,比如每 30 分钟一次吗?
    • 你的意思是,缓存文件系统中的所有文件,30分钟后再将缓存与文件系统进行比较?不,这将要求应用程序每 30 分钟再次遍历整个文件系统。在 HDD 存储设备上浏览所有内容可能需要长达 12 小时。
    • 您的答案是“仅链接”答案,在 Stack Overflow 上不被视为正确答案。您应该在答案本身中解释链接内容的要点。链接可能被破坏。至少您应该提及链接所链接的内容。
    【解决方案3】:

    【讨论】:

    • 这个答案类似于 Sheetal Mohan Sharma 发布的答案。这个例子的问题是应用程序正在遍历文件系统上的所有目录,并且它显式地注册了它们。这将要求应用程序注册超过一百万个目录,这不是一个合适的解决方案。这种方法的性能影响会很大,使应用程序无法使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    相关资源
    最近更新 更多