首页 > 其他分享 >Jdk1.7本地文件监控

Jdk1.7本地文件监控

时间:2023-02-12 20:36:46浏览次数:43  
标签:return String 本地 Jdk1.7 key path 监控 import public

Jdk实现本地文件监听

监听实现: ConfigDirWatchContext

package com.jinko.apollo;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import de.schlichtherle.io.File;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static java.nio.file.StandardWatchEventKinds.*;

/**
 * @author xxx
 */
public class ConfigDirWatchContext {
    private static final Logger logger = LoggerFactory.getLogger(ConfigDirWatchContext.class);
    private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new ThreadFactoryBuilder().setNameFormat("ConfigDirWatchContextPool -%d").build(), new ThreadPoolExecutor.AbortPolicy());
    private static WatchService WATCHER = null;
    private static final String SUFFIX = ".properties";
    private static final Map<String, Properties> CONFIGS = new ConcurrentHashMap<>();
    private static final List<String> FAIL_PATH = new ArrayList<>(0);
    private static final Path ROOT_PATH = Paths.get("/app/ecology/filesystem/config/");
    private static final ConfigDirWatchContext SINGLE_INSTANCE = new ConfigDirWatchContext();


    public static ConfigDirWatchContext newInstance() {
        return SINGLE_INSTANCE;
    }


    public Map<String, Properties> getConfigs() {
        return Collections.unmodifiableMap(CONFIGS);
    }

    public List<String> getFailList() {
        return Collections.unmodifiableList(FAIL_PATH);
    }

    private ConfigDirWatchContext() {
        recursiveRegister(ROOT_PATH);
        this.watchStart();
    }

    private synchronized WatchService buildWatcher() {
        if (Objects.nonNull(WATCHER)) {
            return WATCHER;
        }
        try {
            return WATCHER = FileSystems.getDefault().newWatchService();
        } catch (Throwable e) {
            logger.info("ConfigDirWatchService Throwable", e);
        }
        throw new RuntimeException("");
    }

    @SneakyThrows
    private void recursiveRegister(Path path) {
        // 这里的监听必须是目录
        if (!path.toFile().exists() && !path.toFile().mkdirs()) {
            logger.info("ConfigDirWatchService mkdir error {}", path.toAbsolutePath());
            FAIL_PATH.add(path.toAbsolutePath().toString());
            return;
        }
        // 创建WatchService,它是对操作系统的文件监视器的封装,相对之前,不需要遍历文件目录,效率要高很多
        WatchService watcher = buildWatcher();
        // 注册指定目录使用的监听器,监视目录下文件的变化;
        // PS:Path必须是目录,不能是文件;
        // StandardWatchEventKinds.ENTRY_MODIFY,表示监视文件的修改事件
        path.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY, ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
        Files.list(path).forEach(child -> {
            if (Files.exists(child)) {
                if (Files.isDirectory(child)) {
                    recursiveRegister(child);
                } else if (child.toString().endsWith(SUFFIX)) {
                    CONFIGS.put(getKey(child), read(child));
                }
            }
        });
    }

    private String getKey(Path path) {
        return ROOT_PATH.relativize(path).toString().replace(File.separator, ".");
    }

    private ConfigDirWatchContext watchStart() {
        EXECUTOR.submit(() -> {
            try {
                // 创建一个线程,等待目录下的文件发生变化
                logger.info("watchStart ... ");
                while (true) {
                    // 获取目录的变化:
                    // take()是一个阻塞方法,会等待监视器发出的信号才返回。
                    // 还可以使用watcher.poll()方法,非阻塞方法,会立即返回当时监视器中是否有信号。
                    // 返回结果WatchKey,是一个单例对象,与前面的register方法返回的实例是同一个;
                    WatchKey key = buildWatcher().take();
                    // 处理文件变化事件:
                    // key.pollEvents()用于获取文件变化事件,只能获取一次,不能重复获取,类似队列的形式。
                    for (WatchEvent<?> event : key.pollEvents()) {
                        // event.kind():事件类型
                        if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
                            //事件可能lost or discarded
                            continue;
                        }
                        Watchable watchable = key.watchable();
                        // 返回触发事件的文件或目录的路径(相对路径)
                        Path fullPath = Paths.get(watchable.toString(), event.context().toString());
                        logger.info("path={} , type={}", fullPath, event.kind());
                        handler(fullPath, event);
                    }
                    // 每次调用WatchService的take()或poll()方法时需要通过本方法重置
                    if (!key.reset()) {
                        break;
                    }
                }
            } catch (Throwable e) {
                logger.info("ConfigDirWatchService Throwable", e);
            }
        });
        return this;
    }

    private void handler(Path changePath, WatchEvent event) {
        if (Objects.isNull(event) || Objects.isNull(changePath)) {
            logger.info("hander error {} {} ", changePath, event);
            return;
        }
        if (!Files.isDirectory(changePath)) {
            handlerFile(changePath, event);
            return;
        }
        if (ENTRY_CREATE.name().equals(event.kind().name())) {
            /*  添加新的监听目录 */
            recursiveRegister(changePath);
        } else {
            logger.info("not handler Directory {} {}", changePath, event.kind());
        }
    }

    private void handlerFile(Path changePath, WatchEvent event) {
        if (Objects.isNull(event) || Objects.isNull(changePath) || !changePath.toString().endsWith(SUFFIX)) {
            logger.info("hander error {} {} ", changePath, event);
            return;
        }
        if (ENTRY_CREATE.name().equals(event.kind().name()) || ENTRY_MODIFY.name().equals(event.kind().name())) {
            CONFIGS.put(getKey(changePath), read(changePath));
        } else if (ENTRY_DELETE.name().equals(event.kind().name())) {
            CONFIGS.remove(getKey(changePath));
        } else {
            logger.info("handler {} {}", changePath, event.kind());
        }
    }

    @SneakyThrows
    private Properties read(Path path) {
        Properties properties = new Properties();
        properties.load(Files.newInputStream(path));
        return properties;
    }

    @SneakyThrows
    public static void main(String[] args) throws IOException {
        Map<String, Properties> configs = new ConfigDirWatchContext()
                .watchStart().getConfigs();
//        Thread.sleep(100000000);
    }
}

工具类: ConfigUtils

package com.jinko.apollo;

import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author xxx
 */
public class ConfigUtils {

    private final ConfigDirWatchContext CONTEXT = ConfigDirWatchContext.newInstance();
    private static final String SUFFIX = ".properties";
    private final Map<String, Properties> CONFIGS = CONTEXT.getConfigs();

    public static ConfigUtils newInstance() {
        return new ConfigUtils();
    }

    public String get(String path, String key) {
        return get(path, key, null);
    }

    public String get(String path, String key, String defaultValue) {
        String realKey = String.format("%s%s", path, SUFFIX);
        if (StringUtils.isBlank(path) || !CONFIGS.containsKey(realKey)) {
            return defaultValue;
        }
        return CONFIGS.get(realKey).getProperty(key, defaultValue);
    }

    public Map<String, Properties> getConfigs() {
        return CONFIGS;
    }

    public List<String> getFailPathList() {
        return CONTEXT.getFailList();
    }


    @SneakyThrows
    public static void main(String[] args) {
        ConfigUtils configUtils = newInstance();
        Map<String, Properties> configs = configUtils.getConfigs();
        String key = configUtils.get("bestsign.config", "key");
        String key1 = configUtils.get("", "key");
        String key2 = configUtils.get(null, "key");
        System.out.println(key);
        Thread.sleep(100000);
    }


}
package com.jinko.apollo;

import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author xuyuansheng
 */
public class ConfigUtils {

    private final ConfigDirWatchContext CONTEXT = ConfigDirWatchContext.newInstance();
    private static final String SUFFIX = ".properties";
    private final Map<String, Properties> CONFIGS = CONTEXT.getConfigs();

    public static ConfigUtils newInstance() {
        return new ConfigUtils();
    }

    public String get(String path, String key) {
        return get(path, key, null);
    }

    public String get(String path, String key, String defaultValue) {
        String realKey = String.format("%s%s", path, SUFFIX);
        if (StringUtils.isBlank(path) || !CONFIGS.containsKey(realKey)) {
            return defaultValue;
        }
        return CONFIGS.get(realKey).getProperty(key, defaultValue);
    }

    public Map<String, Properties> getConfigs() {
        return CONFIGS;
    }

    public List<String> getFailPathList() {
        return CONTEXT.getFailList();
    }


    @SneakyThrows
    public static void main(String[] args) {
        ConfigUtils configUtils = newInstance();
        Map<String, Properties> configs = configUtils.getConfigs();
        String key = configUtils.get("bestsign.config", "key");
        String key1 = configUtils.get("", "key");
        String key2 = configUtils.get(null, "key");
        System.out.println(key);
        Thread.sleep(100000);
    }


}
package com.jinko.apollo;

import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author xuyuansheng
 */
public class ConfigUtils {

    private final ConfigDirWatchContext CONTEXT = ConfigDirWatchContext.newInstance();
    private static final String SUFFIX = ".properties";
    private final Map<String, Properties> CONFIGS = CONTEXT.getConfigs();

    public static ConfigUtils newInstance() {
        return new ConfigUtils();
    }

    public String get(String path, String key) {
        return get(path, key, null);
    }

    public String get(String path, String key, String defaultValue) {
        String realKey = String.format("%s%s", path, SUFFIX);
        if (StringUtils.isBlank(path) || !CONFIGS.containsKey(realKey)) {
            return defaultValue;
        }
        return CONFIGS.get(realKey).getProperty(key, defaultValue);
    }

    public Map<String, Properties> getConfigs() {
        return CONFIGS;
    }

    public List<String> getFailPathList() {
        return CONTEXT.getFailList();
    }


    @SneakyThrows
    public static void main(String[] args) {
        ConfigUtils configUtils = newInstance();
        Map<String, Properties> configs = configUtils.getConfigs();
        String key = configUtils.get("bestsign.config", "key");
        String key1 = configUtils.get("", "key");
        String key2 = configUtils.get(null, "key");
        System.out.println(key);
        Thread.sleep(100000);
    }


}

标签:return,String,本地,Jdk1.7,key,path,监控,import,public
From: https://www.cnblogs.com/xysgo/p/16970842.html

相关文章

  • MySQL本地安装配置
    MySQL本地安装配置地址:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-winx64.zip配置出错重开scdeletemysql配环境变量:Path,安装目录\bin安装目录下......
  • office 365 白p指南KMS本地服务器部署详细步骤
    免费激活officeofficehttps://help.coolhub.top/zh-cn/activate/activate-steps.html#密钥激活-联网激活零售(Retail)许可证零售许可证只能使用密钥激活,对于Microsoft......
  • MySql 导出本地全部数据库
    0、参考Mysql一次性备份导出/导入恢复所有数据库1、检查环境配置mysql环境pathC:\ProgramFiles\MySQL\MySQLServer5.7\bin2、导出mysqldump-uroot-p--all-da......
  • 关于win11没有gpedit.msc(本地组策略管理)的解决方案
    转载自https://blog.csdn.net/Xingchen0101/article/details/128943201在本地部署一个bat文件里面粘贴以下文本pushd"%~dp0"dir/bC:\Windows\servicin......
  • python使用lxml库进行本地html文件的内容提取
    从某些网站上得到了一些考试题目,但是人家的排版时:题目、选项、正确答案怎么才能把题目都提取到文件的一列,选项提取到一列,答案提取到一列呢?使用了lxml这个库,不过这个库需......
  • window.performance(前端性能监控并进行上报)
    WebPerformance提供了可以通过的函数(performance属性提供)测试当前网页或者web应用的性能,获取更为精确的原始数据,以毫秒为单位。一般放在window.onload事件中读取各种数据......
  • 高德地图自定义窗体不支持本地图片
    高德地图自定义窗体不支持本地图片我们可以使用谷歌的识图功能将图片转成base64  上传图片后点击查找图片来源   然后点击在新标签页打开图片 此时地址栏......
  • 关于cvat本地版本如何修改地址中的ip
    在使用cvat官方的部署方式后,一般都是使用docker-composeup进行启动,但是访问方式只有localhost:8080这种方式,比如我在内网服务器部署,就需要将localhost改为ip才能在内网机......
  • 可能是最简单的本地GPT3 对话机器人,支持OpenAI 和 Azure OpenAI
    毫无疑问,GPT是目前最火的人工智能方向,已经商用的有OpenAI公司原生的GPT3和ChatGPT,以及微软公司的AzureOpenAIService(暂时还没有包含ChatGPT)。关于他们的各种资料以及......
  • 饱和度 - 监控MySQL的InnoDB Buffer pool 相关的指标
    1. 对于MySQL而言,用什么指标来反映资源有多“满”呢?首先我们要关注MySQL所在机器的CPU、内存、硬盘I/O、网络流量这些基础指标2. MySQL本身也有一些指标来反映饱......