【问题标题】:java api to receive notifications when a file system is mounted安装文件系统时接收通知的java api
【发布时间】:2014-12-02 14:24:33
【问题描述】:

我正在寻找一个允许注册文件系统挂载事件的 Java API,即当文件系统被挂载或卸载时。具体来说,我想知道可移动 USB 设备上的文件系统何时可用,并且还确切知道它是什么类型的 USB 设备。

默认情况下,udev 子系统会提供有关 USB 插拔事件的通知,但不会专门在设备上的文件系统可用时提供通知。可以创建可以分段执行此操作的 udev 规则,例如添加和删​​除设备时创建目录并执行程序。但是我对 udev 规则的经验是语法晦涩难懂,而且它们很脆弱,调试起来也不简单。

我已经按照这篇文章安装了 usbmount:

https://serverfault.com/questions/414120/how-to-get-usb-devices-to-automount-in-ubuntu-12-04-server

虽然我相信这些设备默认是自动安装的。

作为替代方案,我在 /media 上构建了一个 JDK 7 WatcherService,它可以检测 /etc/mtab 中的变化。这可行,但我看到某些 USB 设备上的文件系统仍未准备好的情况——这意味着尝试读取目录会引发异常——即使在 /etc/mtab 中的条目完成后也是如此。我添加了一个定时器来休眠可配置的毫秒数,在大多数情况下,100 毫秒的等待时间有效,但不是 100% 的时间。这意味着增加这个等待时间不是绝对的保证,也不是确定的。

很明显,由于显示了 Nautilus 弹出窗口,因此正在生成挂载事件。我有一个闪存驱动器的案例,它可以将 Nautilus 图标放在启动板菜单中,但在单击打开图标之前它不会安装。

我也看过这些选项:

  • 拖尾 /var/log/syslog;这可能是下一个最佳选择。我看到如下行:

:Dec 2 08:58:07 fred-Inspiron-530 udisksd[1759]: 代表 uid 1000 在 /media/fred/USB DISK1 挂载 /dev/sdk1

我将在此处尝试 WatcherService 以查看是否存在相同的计时问题,即一旦写入此消息,目录是否可读。

  • jlibudev [ github.com/nigelb/jlibudev ] udev 子系统的 Java API 比编写规则要好得多,但它仍然存在不足之处,因为您仍然必须将许多不同的事件拼凑在一起。注意:jlibudev 依赖于 JNA [https://github.com/twall/jna] 和 purejavacomm [github.com/nyholku/purejavacomm,sparetimelabs.com/purejavacomm/purejavacomm.php],它们本身就非常有用。

  • lsusb 提供有关 USB 设备的详细信息,但不提供有关其安装位置的信息。

理想情况下,我想要一个简单的 API,允许使用标准 Java 事件侦听模式注册文件系统挂载/卸载事件。鉴于在宏观层面上正在发生净效应,我想相信这样的 API 存在或至少是可能的。我仍在寻找其他选项的 JDK 7 和 JDK 8 API。

我们将不胜感激任何和所有的指点和帮助。

【问题讨论】:

    标签: java notifications filesystems


    【解决方案1】:

    由于没有与操作系统无关的方法来处理挂载文件系统,因此肯定没有 JDK API 来解决这个问题。我猜这个问题没有得到太多处理(不是很多程序直接处理挂载文件系统),所以不太可能有任何预构建的库等着你。

    在您提到的这些方法中,就特定于平台的程度而言,它们听起来大致相同(仅适用于 Linux),因此性能和编码的易用性只是悬而未决的问题。关于性能,每秒运行一次以上lsusb 是 (a) 一个巨大的 hack :-) 并且 (b) fork+exec 与在进程中运行某些东西相比速度很慢,并且跟踪事件日志会产生很多 (不可预测)为与 USB 安装无关的程序工作以及使您的实现更加脆弱(如果升级操作系统时消息字符串发生变化怎么办?)。关于编程的易用性,使用jna 或JNI 调用libudev/media 上的WatcherService 听起来差不多——使用libudev 似乎是Linux 发行版/用户配置中最便携的选项(我我猜这就是 Nautilus 的用途)。

    但是,为了简化实现(适用于 99% 的用户),很难比 /media 上的 WatcherService 做得更好。为了帮助确保文件系统在使用前可用,我将使用带有某种随机指数退避的循环,在尝试读取目录之间等待的时间量 - 这样你永远不会等待超过必要的时间要挂载的文件系统,您不会消耗大量 CPU 唤醒并尝试读取,并且您不必选择一个无法在任何地方工作的超时数。如果您足够在意以确保您不会束缚一个永远休眠的线程,我会使用ScheduledExecutorService 发出尝试访问文件系统的Runnables,如果它不可用,请安排自己再次运行一点点,否则会提醒你的主线程有一个新的文件系统可以使用某种队列。

    编辑:我刚刚了解到您还可以关注/proc/mounts 文件的更新。希望由于内核负责更新此文件,因此只有在完全挂载时才会显示,尽管我不确定。更多详情,How to interpret /proc/mounts?the Red Hat docs 很有用。

    【讨论】:

      猜你喜欢
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多