欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

动态修改properties配置文件

程序员文章站 2022-06-06 13:18:45
...

在实际的项目中有些数据是临时数据不必要保存到数据库中因此保存到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();