最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java.nio.file.WatchService?實時監(jiān)控文件變化的示例代碼

 更新時間:2022年05月30日 10:33:31   作者:志波同學  
在?Java?語言中,從?JDK7?開始,新增了java.nio.file.WatchService類,用來實時監(jiān)控文件的變化,這篇文章主要介紹了java.nio.file.WatchService?實時監(jiān)控文件變化,需要的朋友可以參考下

在平時的開發(fā)過程中,會有很多場景需要實時監(jiān)聽文件的變化,如下:
1、通過實時監(jiān)控 mysql 的 binlog 日志實現數據同步
2、修改配置文件后,希望系統(tǒng)可以實時感知
3、應用系統(tǒng)將日志寫入文件中,日志監(jiān)控系統(tǒng)可以實時抓取日志,分析日志內容并進行報警
4、類似 ide 工具,可以實時感知管理的工程下的文件變更

在 Java 語言中,從 JDK7 開始,新增了java.nio.file.WatchService類,用來實時監(jiān)控文件的變化。

1.示例代碼

FileWatchedService 類:

package org.learn.file;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.List;

/**
 * 實時監(jiān)控文件的變化
 *
 * @author zhibo
 * @date 2019-07-30 20:37
 */
public class FileWatchedService {
    private WatchService watchService;

    private FileWatchedListener listener;

    /**
     *
     * @param path 要監(jiān)聽的目錄,注意該 Path 只能是目錄,否則會報錯 java.nio.file.NotDirectoryException: /Users/zhibo/logs/a.log
     * @param listener 自定義的 listener,用來處理監(jiān)聽到的創(chuàng)建、修改、刪除事件
     * @throws IOException
     */
    public FileWatchedService(Path path, FileWatchedListener listener) throws IOException {
        watchService = FileSystems.getDefault().newWatchService();
        path.register(watchService,
                /// 監(jiān)聽文件創(chuàng)建事件
                StandardWatchEventKinds.ENTRY_CREATE,
                /// 監(jiān)聽文件刪除事件
                StandardWatchEventKinds.ENTRY_DELETE,
                /// 監(jiān)聽文件修改事件
                StandardWatchEventKinds.ENTRY_MODIFY);
//
//            path.register(watchService,
//                    new WatchEvent.Kind[]{
//                            StandardWatchEventKinds.ENTRY_MODIFY,
//                            StandardWatchEventKinds.ENTRY_CREATE,
//                            StandardWatchEventKinds.ENTRY_DELETE
//                    },
//                    SensitivityWatchEventModifier.HIGH);

        this.listener = listener;
    }

    private void watch() throws InterruptedException {
        while (true) {
            WatchKey watchKey = watchService.take();
            List<WatchEvent<?>> watchEventList = watchKey.pollEvents();
            for (WatchEvent<?> watchEvent : watchEventList) {
                WatchEvent.Kind kind = watchEvent.kind();

                WatchEvent<Path> curEvent = (WatchEvent<Path>) watchEvent;
                if (kind == StandardWatchEventKinds.OVERFLOW) {
                    listener.onOverflowed(curEvent);
                    continue;
                } else if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                    listener.onCreated(curEvent);
                    continue;
                } else if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
                    listener.onModified(curEvent);
                    continue;
                } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
                    listener.onDeleted(curEvent);
                    continue;
                }
            }

            /**
             * WatchKey 有兩個狀態(tài):
             * {@link sun.nio.fs.AbstractWatchKey.State.READY ready} 就緒狀態(tài):表示可以監(jiān)聽事件
             * {@link sun.nio.fs.AbstractWatchKey.State.SIGNALLED signalled} 有信息狀態(tài):表示已經監(jiān)聽到事件,不可以接續(xù)監(jiān)聽事件
             * 每次處理完事件后,必須調用 reset 方法重置 watchKey 的狀態(tài)為 ready,否則 watchKey 無法繼續(xù)監(jiān)聽事件
             */
            if (!watchKey.reset()) {
                break;
            }

        }
    }

    public static void main(String[] args) {
        try {
            Path path = Paths.get("/Users/zhibo/logs/");
            FileWatchedService fileWatchedService = new FileWatchedService(path, new FileWatchedAdapter());
            fileWatchedService.watch();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

FileWatchedListener 類:

package org.learn.file;

import java.nio.file.Path;
import java.nio.file.WatchEvent;

public interface FileWatchedListener {
    void onCreated(WatchEvent<Path> watchEvent);

    void onDeleted(WatchEvent<Path> watchEvent);

    void onModified(WatchEvent<Path> watchEvent);

    void onOverflowed(WatchEvent<Path> watchEvent);
}

FileWatchedAdapter 類:

package org.learn.file;

import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * 文件監(jiān)聽適配器
 *
 * @author zhibo
 * @date 2019-07-31 11:07
 */
public class FileWatchedAdapter implements FileWatchedListener {

    @Override
    public void onCreated(WatchEvent<Path> watchEvent) {
        Path fileName = watchEvent.context();
        System.out.println(String.format("文件【%s】被創(chuàng)建,時間:%s", fileName, now()));
    }

    @Override
    public void onDeleted(WatchEvent<Path> watchEvent) {
        Path fileName = watchEvent.context();
        System.out.println(String.format("文件【%s】被刪除,時間:%s", fileName, now()));
    }

    @Override
    public void onModified(WatchEvent<Path> watchEvent) {
        Path fileName = watchEvent.context();
        System.out.println(String.format("文件【%s】被修改,時間:%s", fileName, now()));
    }

    @Override
    public void onOverflowed(WatchEvent<Path> watchEvent) {
        Path fileName = watchEvent.context();
        System.out.println(String.format("文件【%s】被丟棄,時間:%s", fileName, now()));
    }

    private String now(){
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        return dateFormat.format(Calendar.getInstance().getTime());
    }
}

執(zhí)行以上代碼,啟動監(jiān)控任務,然后我在/Users/zhibo/logs/目錄中創(chuàng)建、修改、刪除文件,命令如下:

在這里插入圖片描述

應用程序感知到文件變化,打印日志如下:

在這里插入圖片描述

2.其實并沒有實時

大家可以看到,監(jiān)控任務基本上是以 10 秒為單位進行日志打印的,也就是說修改一個文件,WatchService 10秒之后才能感知到文件的變化,沒有想象中的那么實時。根據以上的經驗,推測可能是 WatchService 做了定時的操作,時間間隔為 10 秒。通過翻閱源代碼發(fā)現,在 PollingWatchService 中確實存在一個固定時間間隔的調度器,如下圖:

在這里插入圖片描述

該調度器的時間間隔有 SensitivityWatchEventModifier 進行控制,該類提供了 3 個級別的時間間隔,分別為2秒、10秒、30秒,默認值為 10秒。SensitivityWatchEventModifier 源碼如下:

package com.sun.nio.file;

import java.nio.file.WatchEvent.Modifier;

public enum SensitivityWatchEventModifier implements Modifier {
    HIGH(2),
    MEDIUM(10),
    LOW(30);

    private final int sensitivity;

    public int sensitivityValueInSeconds() {
        return this.sensitivity;
    }

    private SensitivityWatchEventModifier(int var3) {
        this.sensitivity = var3;
    }
}

通過改變時間間隔來進行驗證,將

        path.register(watchService,
                /// 監(jiān)聽文件創(chuàng)建事件
                StandardWatchEventKinds.ENTRY_CREATE,
                /// 監(jiān)聽文件刪除事件
                StandardWatchEventKinds.ENTRY_DELETE,
                /// 監(jiān)聽文件修改事件
                StandardWatchEventKinds.ENTRY_MODIFY);

修改為:

    path.register(watchService,
                    new WatchEvent.Kind[]{
                            StandardWatchEventKinds.ENTRY_MODIFY,
                            StandardWatchEventKinds.ENTRY_CREATE,
                            StandardWatchEventKinds.ENTRY_DELETE
                    },
                    SensitivityWatchEventModifier.HIGH);

查看日志,發(fā)現正如我們的推斷,WatchService 正以每 2 秒的時間間隔感知文件變化。
在 stackoverflow 中也有人提出了該問題,問題:Is Java 7 WatchService Slow for Anyone Else,我的 mac 系統(tǒng)中確實存在該問題,由于手頭沒有 windows、linux 系統(tǒng),因此無法進行這兩個系統(tǒng)的驗證。

到此這篇關于java.nio.file.WatchService 實時監(jiān)控文件變化的文章就介紹到這了,更多相關java.nio.file.WatchService 監(jiān)控文件變化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring?Cloud灰度部署實現過程詳解

    Spring?Cloud灰度部署實現過程詳解

    這篇文章主要為大家介紹了Spring?Cloud灰度部署實現過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Java 守護線程_動力節(jié)點Java學院整理

    Java 守護線程_動力節(jié)點Java學院整理

    Java語言機制是構建在JVM的基礎之上的,意思是Java平臺把操作系統(tǒng)的底層給屏蔽起來,所以它可以在它自己的虛擬的平臺里面構造出對自己有利的機制,而語言或者說平臺的設計者多多少少是收到Unix思想的影響,而守護線程機制又是對JVM這樣的平臺湊合,于是守護線程應運而生
    2017-05-05
  • Java線程編程中的主線程講解

    Java線程編程中的主線程講解

    這篇文章主要介紹了Java線程編程中的主線程,是Java入門學習中的基礎知識,需要的朋友可以參考下
    2015-09-09
  • 記一次在idea離線使用maven問題(推薦)

    記一次在idea離線使用maven問題(推薦)

    這篇文章主要介紹了記一次在idea離線使用maven問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Java使用openOffice對于word的轉換及遇到的問題解決

    Java使用openOffice對于word的轉換及遇到的問題解決

    開發(fā)過程中經常會使用java將office系列文檔轉換為PDF, 一般都使用微軟提供的openoffice+jodconverter 實現轉換文檔,下面這篇文章主要給大家介紹了關于Java通過openOffice對于word的轉換及遇到問題的解決方法,需要的朋友可以參考下
    2018-09-09
  • 快速上手Mybatis-plus結構構建過程

    快速上手Mybatis-plus結構構建過程

    這篇文章主要介紹了快速上手Mybatis-plus結構構建過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java類加載器與雙親委派機制和線程上下文類加載器專項解讀分析

    Java類加載器與雙親委派機制和線程上下文類加載器專項解讀分析

    類加載器負責讀取Java字節(jié)代碼,并轉換成java.lang.Class類的一個實例的代碼模塊。本文主要和大家聊聊JVM類加載器ClassLoader的使用,需要的可以了解一下
    2022-12-12
  • Spring Boot靜態(tài)資源路徑的配置與修改詳解

    Spring Boot靜態(tài)資源路徑的配置與修改詳解

    最近在做SpringBoot項目的時候遇到了“白頁”問題,通過查資料對SpringBoot訪問靜態(tài)資源做了總結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-09-09
  • java中駝峰與下劃線的寫法互轉

    java中駝峰與下劃線的寫法互轉

    這篇文章主要介紹了java中駝峰與下橫線的寫法互轉方法,文中先是進行了簡單的介紹,之后跟大家分享了一個自己編寫的工具類的示例代碼,有需要的朋友可以參考借鑒,下面來一起學習學習吧。
    2017-01-01
  • Spring核心之IOC與bean超詳細講解

    Spring核心之IOC與bean超詳細講解

    IOC-Inversion of Control,即控制反轉。它不是什么技術,而是一種設計思想。這篇文章將為大家介紹一下Spring控制反轉IOC的原理,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-10-10

最新評論

丹棱县| 章丘市| 阿城市| 郎溪县| 瑞金市| 新绛县| 郓城县| 塘沽区| 西乌珠穆沁旗| 天水市| 攀枝花市| 仪征市| 九寨沟县| 南木林县| 泰州市| 靖宇县| 托克托县| 大同市| 舟山市| 甘洛县| 龙川县| 玛纳斯县| 鄂伦春自治旗| 阳西县| 仪征市| 顺平县| 如皋市| 微山县| 宝丰县| 汕头市| 商南县| 雷波县| 新干县| 密云县| 广元市| 古蔺县| 张家口市| 洛南县| 从化市| 四子王旗| 习水县|