日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

小师妹学JavaIO之:文件系统和WatchService

發(fā)布時間:2024/2/28 windows 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小师妹学JavaIO之:文件系统和WatchService 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 簡介
  • 監(jiān)控的痛點
  • WatchService和文件系統(tǒng)
  • WatchSerice的使用和實現本質
  • 總結

簡介

小師妹這次遇到了監(jiān)控文件變化的問題,F師兄給小師妹介紹了JDK7 nio中引入的WatchService,沒想到又順道普及了一下文件系統(tǒng)的概念,萬萬沒想到。

監(jiān)控的痛點

小師妹:F師兄最近你有沒有感覺到呼吸有點困難,后領有點涼颼颼的,說話有點不順暢的那種?

沒有啊小師妹,你是不是秋衣穿反了?

小師妹:不是的F師兄,我講的是心里的感覺,那種莫須有的壓力,還有一絲悸動纏繞在心。

別繞彎子了小師妹,是不是又遇到問題了。

更多精彩內容且看:

  • 區(qū)塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續(xù)更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續(xù)更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續(xù)更新
  • java程序員從小工到專家成神之路(2020版)-持續(xù)更新中,附詳細文章教程

更多內容請訪問www.flydean.com

小師妹:還是F師兄懂我,這不上次的Properties文件用得非常上手,每次修改Properties文件都要重啟java應用程序,真的是很痛苦。有沒有什么其他的辦法呢?

辦法當然有,最基礎的辦法就是開一個線程定時去監(jiān)控屬性文件的最后修改時間,如果修改了就重新加載,這樣不就行了。

小師妹:寫線程啊,這么麻煩,有沒有什么更簡單的辦法呢?

就知道你要這樣問,還好我準備的比較充分,今天給你介紹一個JDK7在nio中引入的類WatchService。

WatchService和文件系統(tǒng)

WatchService是JDK7在nio中引入的接口:

監(jiān)控的服務叫做WatchService,被監(jiān)控的對象叫做Watchable:

WatchKey register(WatchService watcher,WatchEvent.Kind<?>[] events,WatchEvent.Modifier... modifiers)throws IOException; WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events)throws IOException;

Watchable通過register將該對象的WatchEvent注冊到WatchService上。從此只要有WatchEvent發(fā)生在Watchable對象上,就會通知WatchService。

WatchEvent有四種類型:

  • ENTRY_CREATE 目標被創(chuàng)建
  • ENTRY_DELETE 目標被刪除
  • ENTRY_MODIFY 目標被修改
  • OVERFLOW 一個特殊的Event,表示Event被放棄或者丟失
  • register返回的WatchKey就是監(jiān)聽到的WatchEvent的集合。

    現在來看WatchService的4個方法:

  • close 關閉watchService
  • poll 獲取下一個watchKey,如果沒有則返回null
  • 帶時間參數的poll 在等待的一定時間內獲取下一個watchKey
  • take 獲取下一個watchKey,如果沒有則一直等待
  • 小師妹:F師兄,那怎么才能構建一個WatchService呢?

    上次文章中說的文件系統(tǒng),小師妹還記得吧,FileSystem中就有一個獲取WatchService的方法:

    public abstract WatchService newWatchService() throws IOException;

    我們看下FileSystem的結構圖:

    在我的mac系統(tǒng)上,FileSystem可以分為三大類,UnixFileSystem,JrtFileSystem和ZipFileSystem。我猜在windows上面應該還有對應的windows相關的文件系統(tǒng)。小師妹你要是有興趣可以去看一下。

    小師妹:UnixFileSystem用來處理Unix下面的文件,ZipFileSystem用來處理zip文件。那JrtFileSystem是用來做什么的?

    哎呀,這就又要扯遠了,為什么每次問問題都要扯到天邊…

    從前當JDK還是9的時候,做了一個非常大的改動叫做模塊化JPMS(Java Platform Module System),這個Jrt就是為了給模塊化系統(tǒng)用的,我們來舉個例子:

    public void useJRTFileSystem(){String resource = "java/lang/Object.class";URL url = ClassLoader.getSystemResource(resource);log.info("{}",url);}

    上面一段代碼我們獲取到了Object這個class的url,我們看下如果是在JDK8中,輸出是什么:

    jar:file:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/rt.jar!/java/lang/Object.class

    輸出結果是jar:file表示這個Object class是放在jar文件中的,后面是jar文件的路徑。

    如果是在JDK9之后:

    jrt:/java.base/java/lang/Object.class

    結果是jrt開頭的,java.base是模塊的名字,后面是Object的路徑。看起來是不是比傳統(tǒng)的jar路徑更加簡潔明了。

    有了文件系統(tǒng),我們就可以在獲取系統(tǒng)默認的文件系統(tǒng)的同時,獲取到相應的WatchService:

    WatchService watchService = FileSystems.getDefault().newWatchService();

    WatchSerice的使用和實現本質

    小師妹:F師兄,WatchSerice是咋實現的呀?這么神奇,為我們省了這么多工作。

    其實JDK提供了這么多類的目的就是為了不讓我們重復造輪子,之前跟你講監(jiān)控文件的最簡單辦法就是開一個獨立的線程來監(jiān)控文件變化嗎?其實…WatchService就是這樣做的!

    PollingWatchService() {// TBD: Make the number of threads configurablescheduledExecutor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(null, r, "FileSystemWatcher", 0, false);t.setDaemon(true);return t;}});}

    上面的方法就是生成WatchService的方法,小師妹看到沒有,它的本質就是開啟了一個daemon的線程,用來接收監(jiān)控任務。

    下面看下怎么把一個文件注冊到WatchService上面:

    private void startWatcher(String dirPath, String file) throws IOException {WatchService watchService = FileSystems.getDefault().newWatchService();Path path = Paths.get(dirPath);path.register(watchService, ENTRY_MODIFY);Runtime.getRuntime().addShutdownHook(new Thread(() -> {try {watchService.close();} catch (IOException e) {log.error(e.getMessage());}}));WatchKey key = null;while (true) {try {key = watchService.take();for (WatchEvent<?> event : key.pollEvents()) {if (event.context().toString().equals(fileName)) {loadConfig(dirPath + file);}}boolean reset = key.reset();if (!reset) {log.info("該文件無法重置");break;}} catch (Exception e) {log.error(e.getMessage());}}}

    上面的關鍵方法就是path.register,其中Path是一個Watchable對象。

    然后使用watchService.take來獲取生成的WatchEvent,最后根據WatchEvent來處理文件。

    總結

    道生一,一生二,二生三,三生萬物。一個簡簡單單的功能其實背后隱藏著…道德經,哦,不對,背后隱藏著道的哲學。

    本文的例子https://github.com/ddean2009/learn-java-io-nio

    本文作者:flydean程序那些事

    本文鏈接:http://www.flydean.com/java-io-file-watchservice/

    本文來源:flydean的博客

    歡迎關注我的公眾號:程序那些事,更多精彩等著您!

    總結

    以上是生活随笔為你收集整理的小师妹学JavaIO之:文件系统和WatchService的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。