Java实现的properties文件动态修改并自动保存工具类

我会详细讲解“Java实现的properties文件动态修改并自动保存工具类”的完整攻略,包括实现细节和示例。

什么是properties文件?

在Java语言中,Properties类是一种用于表示一组持久性属性的集合的取消息类。在程序中,常常需要读取一些配置信息,比如数据库连接字符串、账号密码等信息,这些信息被经常被存储在一个文本文件中,这个文本文件的格式就是properties文件。properties文件中存储着如下格式的信息:

#配置文件示例
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=12345

实现思路

实现一个能够动态修改properties文件并自动保存的工具类的过程如下:

  1. 加载properties文件:使用Properties类的load方法读取properties文件。
  2. 修改properties文件:使用Properties类的setProperty方法设置新值。
  3. 保存properties文件:使用Properties类的store方法将修改后的properties文件保存在硬盘上。

实现细节

  1. 加载properties文件:使用Properties类的load方法读取properties文件。
//加载properties文件
Properties prop = new Properties();
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config.properties");
prop.load(inputStream);
  1. 修改properties文件:使用Properties类的setProperty方法设置新值。
//修改properties文件
prop.setProperty("db.url", "jdbc:mysql://localhost:3306/test_modify");
  1. 保存properties文件:使用Properties类的store方法将修改后的properties文件保存在硬盘上。
//保存properties文件
OutputStream outputStream = new FileOutputStream("config.properties");
prop.store(outputStream, "update property");
  1. 为了能够动态修改properties文件并自动保存。可以使用Java中的NIO(New IO)技术监听文件修改事件,用线程池实现异步保存属性自动化到磁盘。

示例1

下面的示例代码展示了如何打开config.properties文件,修改属性内容并保存更改。

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

public class PropertiesTool {

    private Properties prop = new Properties();
    private String propFilePath = "config.properties";
    private Long lastModifed;

    public PropertiesTool() {
        super();
        try {
            initProperties();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initProperties() throws Exception {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(propFilePath);
        prop.load(inputStream);

        lastModifed = PropertiesTool.class.getResource(propFilePath).openConnection().getLastModified();
        //开启自动保存线程
        new Thread(new AutoSave(), "PropertiesToolAutoSaveThread").start();
    }

    public void updateProperty(String name, String value) {
        prop.setProperty(name, value);
    }

    public String getProperty(String name) {
        return prop.getProperty(name);
    }

    class AutoSave implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    Thread.sleep(1000);
                    Long nowModifed = PropertiesTool.class.getResource(propFilePath).openConnection().getLastModified();
                    if (nowModifed > lastModifed) {
                        OutputStream outputStream = new FileOutputStream(PropertiesTool.class.getResource(propFilePath).getFile());
                        prop.store(outputStream, "update property");
                        lastModifed = nowModifed;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {
            PropertiesTool tool = new PropertiesTool();

            //输出修改前的内容
            System.out.println(tool.getProperty("db.url"));

            //修改属性值
            tool.updateProperty("db.url", "jdbc:mysql://localhost:3306/test_modify");

            //属性值修改后对应的配置文件自动保存
            System.out.println(tool.getProperty("db.url"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

示例2

下面的示例代码展示了如何监听config.properties文件内容修改事件,并在修改后自动保存修改后的属性到配置文件。

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.*;
import java.util.Properties;
import java.util.concurrent.Executors;

public class PropertiesTool {

    private Properties prop = new Properties();
    private String propFilePath = "config.properties";
    private Long lastModifed;

    public PropertiesTool() {
        super();
        try {
            initProperties();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initProperties() throws Exception {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(propFilePath);
        prop.load(inputStream);

        lastModifed = PropertiesTool.class.getResource(propFilePath).openConnection().getLastModified();
        //开启自动保存线程
        Executors.newSingleThreadExecutor().execute(new AutoSave());
        //添加属性更新监听器
        Path path = Paths.get(this.getClass().getResource(propFilePath).toURI());
        WatchService watchService = FileSystems.getDefault().newWatchService();
        path.getParent().register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
        Executors.newSingleThreadExecutor().execute(new WatchRunnable(watchService));
    }

    public void updateProperty(String name, String value) {
        prop.setProperty(name, value);
    }

    public String getProperty(String name) {
        return prop.getProperty(name);
    }

    class AutoSave implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    Thread.sleep(1000);
                    Long nowModifed = PropertiesTool.class.getResource(propFilePath).openConnection().getLastModified();
                    if (nowModifed > lastModifed) {
                        OutputStream outputStream = new FileOutputStream(PropertiesTool.class.getResource(propFilePath).getFile());
                        prop.store(outputStream, "update property");
                        lastModifed = nowModifed;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class WatchRunnable implements Runnable {
        private WatchService watchService;

        public WatchRunnable(WatchService watchService) {
            this.watchService = watchService;
        }

        @Override
        public void run() {
            try {
                while (true) {
                    WatchKey watchKey = watchService.take();
                    for (WatchEvent event : watchKey.pollEvents()) {
                        if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY &&
                                event.context().toString().equals(propFilePath)) {
                            System.out.println("detect properties file changed...");
                            reload();
                            break;
                        }
                    }
                    watchKey.reset();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void reload() throws Exception {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(propFilePath);
        prop.load(inputStream);
    }

    public static void main(String[] args) {
        try {
            PropertiesTool tool = new PropertiesTool();

            //等待监听线程启动
            Thread.sleep(1000);

            //输出修改前的内容
            System.out.println(tool.getProperty("db.url"));

            //修改属性值
            tool.updateProperty("db.url", "jdbc:mysql://localhost:3306/test_modify");

            //属性值修改后对应的配置文件自动保存
            System.out.println(tool.getProperty("db.url"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

总结

通过这个工具类的实现,我们可以实现某些需要动态修改配置文件的功能,而且能够自动保存修改后的值到配置文件中,大大提高了程序的健壮性和可维护性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现的properties文件动态修改并自动保存工具类 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java System类详解_动力节点Java学院整理

    Java System类详解_动力节点Java学院整理 什么是System类? System类是Java程序中提供的一个包含了一些系统级别的属性和控制操作的类。在Java程序中,我们可以使用System类来读取和设置系统的属性、读写标准的输入流、创建和操纵java虚拟机和Java程序等。 System类中常见的方法 1. System.getProperty…

    Java 2023年5月24日
    00
  • java安全编码指南之:对象构建操作

    Java安全编码指南之对象构建操作 在Java编程中,对象构建操作是非常常见的操作,但如果不正确处理这些操作,就容易出现安全风险。这里我们将介绍一些关于对象构建操作的安全编码指南。 避免使用反射 API 的 newInstance 方法 反射 API 的 newInstance 方法可以通过 Class 对象动态实例化对象,但是存在一些安全风险。例如,如果创…

    Java 2023年5月20日
    00
  • Spring Boot中使用 Spring Security 构建权限系统的示例代码

    下面是详细讲解“Spring Boot中使用 Spring Security 构建权限系统的示例代码”的完整攻略,包含了两条示例: 1. 构建Spring Boot项目 首先,我们需要构建一个Spring Boot项目,可以使用Maven或Gradle来管理依赖并生成项目文件。 在项目中添加以下依赖: <dependency> <group…

    Java 2023年5月20日
    00
  • 使用Spring Boot 2.x构建Web服务的详细代码

    下面就是针对使用Spring Boot 2.x构建Web服务的完整攻略: 1. 创建Spring Boot项目 首先,我们需要在IDE或者命令行中创建一个Spring Boot项目。使用IDE可以直接创建一个Spring Boot项目模板;使用命令行则需要使用Maven构建,具体做法如下: 首先,我们需要在本地装好Maven,然后在命令行中输入 mvn ar…

    Java 2023年5月19日
    00
  • Docker学习笔记之Docker部署Java web系统

    Docker学习笔记之Docker部署Java web系统 本文将会详细介绍如何使用Docker来部署Java web系统。 步骤 步骤1:编写Dockerfile 首先需要编写一个Dockerfile,用于构建镜像。Dockerfile 中需要包含以下内容: FROM openjdk:8-jdk-alpine COPY target/myapp.war /…

    Java 2023年5月19日
    00
  • java删除文件和文件夹具体实现

    当我们需要清理旧数据或者卸载应用程序时,通常需要删除一些文件或者文件夹。下面我来讲解一下Java中如何删除文件和文件夹的实现过程。 删除文件 Java中删除文件的方式非常简单,使用Java的File类提供的delete()方法即可。该方法有一个返回值,表示是否成功删除文件。 例如,我有一个名为test.txt的文件,它的绝对路径为C:\Users\usern…

    Java 2023年5月20日
    00
  • Spring Boot 自动配置的实现

    Spring Boot自动配置是Spring Boot的一个重要特性,它可以帮助我们快速构建应用程序,减少配置工作。以下是Spring Boot自动配置的实现的详细攻略: 自动配置原理 Spring Boot自动配置的原理是基于Spring的条件化配置机制。Spring Boot会根据应用程序的classpath、配置文件和其他条件来自动配置应用程序。如果应…

    Java 2023年5月15日
    00
  • java 汉诺塔Hanoi递归、非递归(仿系统递归)和非递归规律 实现代码

    Java实现汉诺塔问题的递归解法 汉诺塔问题:有三根相邻的柱子,标号为a、b、c,其中a柱子上有n个直径大小各不相同的圆盘,按从小到大的顺序依次从上到下叠放。要把所有盘子一个一个移动到另一个柱子上,条件是每次只能移动一个盘子,且不能出现大盘压小盘的情况。 看到这个问题,我们第一时间可以想到递归。为了更好的理解递归,我们可以先从最简单的情况开始理解。 当只有1…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部