我会详细讲解“Java实现的properties文件动态修改并自动保存工具类”的完整攻略,包括实现细节和示例。
什么是properties文件?
在Java语言中,Properties类是一种用于表示一组持久性属性的集合的取消息类。在程序中,常常需要读取一些配置信息,比如数据库连接字符串、账号密码等信息,这些信息被经常被存储在一个文本文件中,这个文本文件的格式就是properties文件。properties文件中存储着如下格式的信息:
#配置文件示例
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=12345
实现思路
实现一个能够动态修改properties文件并自动保存的工具类的过程如下:
- 加载properties文件:使用Properties类的load方法读取properties文件。
- 修改properties文件:使用Properties类的setProperty方法设置新值。
- 保存properties文件:使用Properties类的store方法将修改后的properties文件保存在硬盘上。
实现细节
- 加载properties文件:使用Properties类的load方法读取properties文件。
//加载properties文件
Properties prop = new Properties();
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config.properties");
prop.load(inputStream);
- 修改properties文件:使用Properties类的setProperty方法设置新值。
//修改properties文件
prop.setProperty("db.url", "jdbc:mysql://localhost:3306/test_modify");
- 保存properties文件:使用Properties类的store方法将修改后的properties文件保存在硬盘上。
//保存properties文件
OutputStream outputStream = new FileOutputStream("config.properties");
prop.store(outputStream, "update property");
- 为了能够动态修改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技术站