在实际的项目中有些数据是临时数据不必要保存到数据库中因此保存到properties配置文件中也是不错的选择。
但是保存在文件中的弊端就是如果要修改就需要修改配置文件了,做成可视化的配置界面有点偏移主题了。
以下代码参考的log4j-x-x.jar中的文件并做少许更改。
具体代码程序实现:扫描文件类FileWatchdog.java
import java.io.File;
/**
Check every now and then that a certain file has not changed. If it
has, then call the {@link #doOnChange} method.
@author Ceki Gülcü
@since version 0.9.1
@update zhangyq
@date 2014-4-28 10:54:00
*/
public abstract class FileWatchdog extends Thread {
/**
The default delay between every file modification check, set to 60
seconds. */
static final public long DEFAULT_DELAY = 60000;
/**
The name of the file to observe for changes.
*/
protected String filename;
/**
The delay to observe between every check. By default set {@link
#DEFAULT_DELAY}. */
protected long delay = DEFAULT_DELAY;
File file;
long lastModif = 0;
boolean warnedAlready = false;
boolean interrupted = false;
protected FileWatchdog(String filename) {
this.filename = filename;
file = new File(filename);
setDaemon(true);
checkAndConfigure();
}
/**
Set the delay to observe between each check of the file changes.
*/
public void setDelay(long delay) {
this.delay = delay;
}
abstract protected void doOnChange();
protected void checkAndConfigure() {
boolean fileExists;
try {
fileExists = file.exists();
} catch (SecurityException e) {
interrupted = true; // there is no point in continuing
return;
}
if (fileExists) {
long l = file.lastModified(); // this can also throw a SecurityException
if (l > lastModif) { // however, if we reached this point this
lastModif = l; // is very unlikely.
doOnChange();
warnedAlready = false;
}
} else {
if (!warnedAlready) {
warnedAlready = true;
}
}
}
public void run() {
while (!interrupted) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
// no interruption expected
}
checkAndConfigure();
}
}
}
该类监测是否修改并提供一个抽象方法
abstract protected void doOnChange();
在文件修改后要做的下一步操作。
具体的业务需求是:将配置文件中的数据保存到一个Map<String,String>集合中一旦修改了该配置文件集合中的数据同时也做修改,具体代码实现:
/**
* Info: 动态加载*.properties文件
* Date: 2014-4-28 14:22:54
* @author zhangyq
*
*/
public class PropertiesFileDynamicLoadingUtil {
private static Map<String, String> fileProperty;
public static Map<String, String> getFileProperty() {
return fileProperty;
}
/**
*
* @param configFilename 文件的绝对路径
* @param delay 检验文件的间隔时间段
*/
public static void configureAndLoad(String configFilename, long delay) {
PropertyWatchdog pdog = new PropertyWatchdog(configFilename);
pdog.setDelay(delay);
pdog.start();
}
//-------------------------------------- 静态内部类定义 --------------------------
/**
* Info: 动态读取配置文件的信息
* @author zhangyq
*/
static class PropertyWatchdog extends FileWatchdog {
/**
* 加载配置文件
* @param props
* @return
*/
public static Map<String, String> loadProperites(Properties props){
fileProperty = new HashMap<String, String>();
Set<Entry<Object, Object>> entrySet = props.entrySet();
for (Entry<Object, Object> entry : entrySet) {
fileProperty.put(((String) entry.getKey()).trim(), ((String) entry.getValue()).trim());
}
return fileProperty;
}
/**
* 构造函数
* @param configFileName 绝对路径
*/
PropertyWatchdog(String filename){
super(filename);
}
@Override
protected void doOnChange() {
Properties props = new Properties();
FileInputStream istream = null;
try {
istream = new FileInputStream(filename);
props.load(istream);
istream.close();
}
catch (Exception e) {
return;
} finally {
if(istream != null) {
try {
istream.close();
} catch(Throwable ignore) {
}
}
}
// TODO
loadProperites(props);
}
}
//--------------------------------------end 静态内部类定义 end--------------------------
}
具体测试和正式调用代码为:path参数为绝对路径
PropertiesFileDynamicLoading.configureAndLoad(path, 15);
Map<String, String> map = PropertiesFileDynamicLoading.getFileProperty();