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

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

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

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

在 Java 語(yǔ)言中,從 JDK7 開始,新增了java.nio.file.WatchService類,用來(lái)實(shí)時(shí)監(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;

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

    private FileWatchedListener listener;

    /**
     *
     * @param path 要監(jiān)聽的目錄,注意該 Path 只能是目錄,否則會(huì)報(bào)錯(cuò) java.nio.file.NotDirectoryException: /Users/zhibo/logs/a.log
     * @param listener 自定義的 listener,用來(lái)處理監(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 有兩個(gè)狀態(tài):
             * {@link sun.nio.fs.AbstractWatchKey.State.READY ready} 就緒狀態(tài):表示可以監(jiān)聽事件
             * {@link sun.nio.fs.AbstractWatchKey.State.SIGNALLED signalled} 有信息狀態(tài):表示已經(jīng)監(jiān)聽到事件,不可以接續(xù)監(jiān)聽事件
             * 每次處理完事件后,必須調(diào)用 reset 方法重置 watchKey 的狀態(tài)為 ready,否則 watchKey 無(wú)法繼續(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)建,時(shí)間:%s", fileName, now()));
    }

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

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

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

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

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

在這里插入圖片描述

應(yīng)用程序感知到文件變化,打印日志如下:

在這里插入圖片描述

2.其實(shí)并沒有實(shí)時(shí)

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

在這里插入圖片描述

該調(diào)度器的時(shí)間間隔有 SensitivityWatchEventModifier 進(jìn)行控制,該類提供了 3 個(gè)級(jí)別的時(shí)間間隔,分別為2秒、10秒、30秒,默認(rèn)值為 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;
    }
}

通過改變時(shí)間間隔來(lái)進(jìn)行驗(yàn)證,將

        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ā)現(xiàn)正如我們的推斷,WatchService 正以每 2 秒的時(shí)間間隔感知文件變化。
在 stackoverflow 中也有人提出了該問題,問題:Is Java 7 WatchService Slow for Anyone Else,我的 mac 系統(tǒng)中確實(shí)存在該問題,由于手頭沒有 windows、linux 系統(tǒng),因此無(wú)法進(jìn)行這兩個(gè)系統(tǒng)的驗(yàn)證。

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

相關(guān)文章

  • Spring?Cloud灰度部署實(shí)現(xiàn)過程詳解

    Spring?Cloud灰度部署實(shí)現(xiàn)過程詳解

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

    Java 守護(hù)線程_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

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

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

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

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

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

    Java使用openOffice對(duì)于word的轉(zhuǎn)換及遇到的問題解決

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

    快速上手Mybatis-plus結(jié)構(gòu)構(gòu)建過程

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

    Java類加載器與雙親委派機(jī)制和線程上下文類加載器專項(xiàng)解讀分析

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

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

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

    java中駝峰與下劃線的寫法互轉(zhuǎn)

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

    Spring核心之IOC與bean超詳細(xì)講解

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

最新評(píng)論

佛冈县| 苍山县| 西藏| 抚顺县| 曲阳县| 滨海县| 大洼县| 共和县| 如东县| 沅江市| 沁阳市| 固安县| 宕昌县| 定襄县| 新龙县| 全南县| 莎车县| 准格尔旗| 任丘市| 克拉玛依市| 邳州市| 安西县| 措美县| 东宁县| 旅游| 马尔康县| 台前县| 静安区| 蓝山县| 兰考县| 和平区| 广昌县| 青冈县| 聂荣县| 甘南县| 天柱县| 慈溪市| 兴山县| 邯郸市| 和龙市| 资阳市|