2014-12-02 64 views
4

我正在尋找一個Java API,它將允許註冊文件系統掛載事件,即文件系統掛載或卸載時。具體而言,我想知道何時可移動USB設備上的文件系統可用,並且也知道它是什麼類型的USB設備。java api在安裝文件系統時接收通知

udev子系統在USB插頭上提供通知,並在默認情況下拔出事件,但不是在設備上的文件系統可用時。可以創建udev規則,這些規則可以分片完成,例如創建目錄並在添加和刪除設備時執行程序。但是我對udev規則的使用經驗是,這個語法很神祕,而且它們很脆弱,不容易調試。每這篇文章

我已經安裝了usbmount:

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

雖然我相信這些設備是由默認automouting。

作爲替代,我構建了一個JDK 7 WatcherService on/media,它可以檢測/ etc/mtab中的更改。這種方式很有效,但我曾經看到過一些USB設備上的文件系統還沒有準備好的情況 - 這意味着即使在/ etc/mtab中的條目被創建之後,嘗試讀取該目錄的操作也會拋出異常。我添加了一個定時器,可以在一個可配置的毫秒數內進行休眠,並且在大多數情況下,100ms的等待時間可以工作,但不是100%的時間。這意味着增加這個等待時間不是絕對的保證也不是確定性的。

很明顯,在某些低級別,正在生成掛載事件,因爲顯示了Nautilus彈出窗口。我有一個閃存驅動器的情況下,將Nautilus圖標放入啓動板菜單,但它不會安裝,直到單擊圖標打開。

我也看了一下這些選項:

  • 拖尾的/ var/log/syslog的;這可能是下一個最佳選擇。我看到像下面的行:

:12月02日8點58分07秒fred的-靈-530 udisksd [1759]:代表的UID 1000

安裝的/ dev/sdk1在/媒體/ fred的/ USB DISK1

我打算在這裏嘗試一個WatcherService,看看是否存在相同的時間問題,即一旦寫入該消息就可以讀取目錄。

  • jlibudev [github.com/nigelb/jlibudev]好多的Java API來的udev子系統比寫規則,但它仍然未能在你仍然有一塊多種不同的事件一起。 NB: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。

任何和所有的指針和援助將不勝感激。

回答

1

由於不存在與操作系統無關的方式來處理掛載文件系統,因此肯定沒有JDK API。我猜這個問題沒有得到太多處理(沒有很多程序直接處理掛載文件系統),所以不太可能有任何預建的庫在等着你。

在你提到的方法中,它們在平臺特定方面(所有Linux都是如此)方面聽起來大致相同,所以只留下作爲開放問題的性能和易編碼性。關於性能,運行lsusb不止一次是(a)一個巨大的黑客:-)和(b)fork + exec相比運行正在處理的內容來說是緩慢的,並且拖尾事件日誌將創建大量(不可預知的)爲您的程序工作,這與USB掛載無關,並使您的實現更脆弱(如果升級操作系統時消息字符串發生了變化,該怎麼辦?)。關於編程的簡易性,使用jna或JNI調用libudevWatcherService/media聲音大約相等 - 使用libudev似乎是跨Linux發行版/用戶配置(我猜這就是鸚鵡螺使用的)最便攜的選項。

但是,爲了簡化實施,對於99%的用戶來說,這很難做到比WatcherService更好的/media。爲了確保文件系統在使用之前可用,我只是使用一個循環,在嘗試讀取目錄之間等待的時間量中使用某種隨機指數回退 - 這樣,您永遠不會等待更長的時間要掛載的文件系統,您不會耗費大量的CPU喚醒並嘗試讀取,而且您不必選擇一個無法在任何地方工作的單個超時編號。如果你足夠小心,以確保你不拘束一個線程永遠睡覺,我會使用ScheduledExecutorService發出Runnable s試圖訪問文件系統,如果它不可用安排自己再次運行一次,否則警告您的主線程可以使用某種類型的隊列使用新的文件系統。

編輯:我剛剛得知您還可以觀察/proc/mounts文件的更新。希望由於內核負責更新這個文件,只有當它們完全掛載時纔會顯示,儘管我不確定。欲瞭解更多詳情,How to interpret /proc/mounts?the Red Hat docs是有用的。