posts - 156,  comments - 601,  trackbacks - 0
针对于JDK本身提供的Properties类,增加了以下功能:
 * 提供指定文件的读写编码支持 Properties使用的编码与当前操作系统有关。一般为 unicode
 * 支持Properties变量的使用。如果 a=123 \n b=${a}456
 * 当文件修改时,自动重新读取。

下面我把源代码粘于下面,供大家交流与学习之用,如有什么问题也希望大家能回复我。

使用方法:
 a util tool which inpackaged Properties class just for easy to use. notice
 that 
default Properties while loading from file which encodes by which you
 specified. it provide a more convient way to use language encoding.
 
 
new feature: 1. add variable support. variable's format look like as ${}
                  notice that variable is only kown as it defined above it.
                 
for example:
                      v1
=abc
                      v2
=ccc
                      v3
=${v1} #here v3's value is abc
                      v4=${v3} #here v4's value is blank instead of ddd
                      v5=ddd
 
   demo 
for the feature:
      now we have a properties file the content as bellow:
      firstname
=Matthew
      lastname
=Xie
      age
=26
      gender
=male
      fullname
=${firstname}.${lastname}
      city
=bei jing
      address
=${city} fengtai
      city_cn
=丰台
      
   here
's our demo source code to show how to use this class.
   
     String myTestPath 
= "test.ini";
     SimpleIniUtil simpleIniUtil 
= null;
        
     simpleIniUtil 
= new SimpleIniUtil();
     
     
// set the reload enabled. default is false.
     
// if setted true, after iniFile changed then when read the properties values it will reload it. 
     simpleIniUtil.setReloadOnchange(true);
     
     
try {
          
//with default encoding open properties file
          simpleIniUtil.loadFile(myTestPath);
          
          
//with specified encoding open properties file
          
//and if the specified encoding not found it will throw a exception
          simpleIniUtil.loadFile(myTestPath, "GB2312");
          
          
//here we print out all the properties
          System.out.println(simpleIniUtil.toString());
          
//the print out result would like as follow:
          Properties values{fullname=Matthew.Xie,address=bei jing fengtai,
          age
=26,gender=male,lastname=Xie,firstname=Matthew,city=bei jing,}
          
          
//get string properties of address
          String address = simpleIniUtil.getPropertiesValue("address");
          
          
//get string properties of address
          
//           with default value "beijing" if the properties name not found
          address = simpleIniUtil.getPropertiesValue("address""beijing");
          
          
//get integer properties of age 
          
//          with defaut value 26 if the properties name not found
          int age = simpleIniUtil.getPropertiesInteger("age"26);
          
          
//set string value and return the previous value of the specified key 
              in this property list, or null if it did not have one.
          Object retObj 
= simpleIniUtil.setPropertiseValue(lastname, "hello");
          
if (retObj != null) {
              String oldLastName 
= (String) retObj;
          }
          
          
////store the properties file
          
//store to the opened file
          simpleIniUtil.store();
          
          
//store to the specified file
          simpleIniUtil.store("/home/test/another.ini");
          
//store to the specified file with comment
          simpleIniUtil.store("/home/test/another.ini""Matt update it");
          
/*
              //the result should be as follow
              #Matt update it
              #update time:2006-05-24 11:19:00
              age=
              
              
          * /
          
          
      } catch (IOException e) {
          // here we should deal the exception
      }    
 

Author:
Matthew Xie
Since:
2006-01-08


源代码:
  1 
  2 import java.io.BufferedReader;
  3 import java.io.BufferedWriter;
  4 import java.io.File;
  5 import java.io.FileInputStream;
  6 import java.io.FileWriter;
  7 import java.io.IOException;
  8 import java.io.InputStream;
  9 import java.io.InputStreamReader;
 10 import java.io.Serializable;
 11 import java.text.DateFormat;
 12 import java.text.SimpleDateFormat;
 13 import java.util.ArrayList;
 14 import java.util.Date;
 15 import java.util.Iterator;
 16 import java.util.LinkedHashMap;
 17 import java.util.LinkedList;
 18 import java.util.List;
 19 import java.util.Map;
 20 import java.util.Set;
 21 
 22 import org.apache.commons.lang.StringUtils;
 23 import org.apache.log4j.Logger;
 24 
 25 
 26 public class SimpleIniUtil implements Serializable {
 27 
 28     /*
 29      * log for this class
 30      */
 31     private static final Logger LOGGER = Logger.getLogger(SimpleIniUtil.class);
 32 
 33     /* serail version uid */
 34     private static final long serialVersionUID = 4841183980762719179L;
 35 
 36     private String iniFile = null;
 37 
 38     private Map<String, String> propContent;
 39 
 40     private String defaultEncode = "GBK";
 41     
 42     private boolean isReloadOnchange = false;
 43     
 44     private long fileTime;
 45 
 46     /**
 47      * default constructor method
 48      */
 49     public SimpleIniUtil() {
 50         propContent = new LinkedHashMap<String, String>();
 51     }
 52     
 53     /**
 54      * set the load file encode
 55      * @param encode
 56      */
 57     public void setEncode(String encode) {
 58         this.defaultEncode = encode;
 59     }
 60     
 61     /**
 62      * constructor method
 63      * @param iniFile full properties file path
 64      */
 65     public SimpleIniUtil(String iniFile) {
 66         this();
 67         this.setIniFile(iniFile);
 68     }
 69 
 70     /**
 71      * get the full properties file path
 72      * @return file path
 73      */
 74     public String getIniFile() {
 75         return iniFile;
 76     }
 77 
 78     /**
 79      * set the properties file path
 80      * @param iniFile full properties file path
 81      */
 82     public void setIniFile(String iniFile) {
 83         this.iniFile = iniFile;
 84     }
 85 
 86     /**
 87      * load the properties content from the file
 88      * @return properteis content from the file
 89      * @throws IOException IO about exception will throw out
 90      */
 91     public Map<String, String> loadFile() throws IOException {
 92         return this.loadFile(this.iniFile);
 93     }
 94 
 95     
 96     /**
 97      * load the propeties file by specified file path
 98      * @param iniFile full file path
 99      * @return properteis content from the file
100      * @throws IOException IO about exception will throw out
101      */
102     public Map<String, String> loadFile(String iniFile) throws IOException {
103         return this.loadFile(iniFile, this.defaultEncode);
104     }
105 
106     /**
107      * load the propeties file by specified file path and encodign
108      * 
109      * @param instream input stream object
110      * @param encode specified encoding
111      * @return map of properteis content from the file
112      * @throws IOException IO about exception will throw out
113      */
114     public Map<String, String> loadFile(InputStream instream, String encode) throws IOException {
115         
116         this.defaultEncode = encode;
117         
118         BufferedReader in = new BufferedReader(new InputStreamReader(instream, encode));
119         String lineStr = null;
120         int commentPos = -1;
121         int valueBreakPos = -1;
122         String key = null;
123         String value = "";
124         int variabesNum = 0;
125         String variableKey = null;
126         
127         while ((lineStr = in.readLine()) != null) {
128             lineStr = lineStr.trim();
129             if (lineStr.equals("")) {
130                 continue;
131             }
132             if (lineStr.startsWith("#")) {
133                 continue;
134             }
135 
136             commentPos = lineStr.indexOf("#");
137             if (commentPos != -1) {
138                 lineStr = lineStr.substring(0, commentPos);
139             }
140             valueBreakPos = lineStr.indexOf("=");
141             if (valueBreakPos == -1) {
142                 setPropertiseValue(lineStr, "");
143             } else {
144                 key = lineStr.substring(0, valueBreakPos).trim();
145                 value = lineStr.substring(++valueBreakPos, lineStr.length()).trim();
146                 if (value.indexOf("${"!= -1) {
147                     
148                     List<String> variables = parseVaraibles(value);
149                     if (variables != null) {
150                         variabesNum = variables.size();
151                         for (int i = 0; i < variabesNum; i++) {
152                             variableKey = variables.get(i);
153                             if (variableKey != null && !variableKey.equals(key)) {
154                                 value = StringUtils.replace(value, "${" + variableKey + "}"
155                                         getPropertiesValue(variableKey, ""));
156                             }
157                         }
158                     }
159                 }
160                 setPropertiseValue(key, value);
161             }
162         }
163         in.close();
164 
165         return this.propContent;
166     }
167     
168     /**
169      * load the propeties file by specified file path and encodign
170      * @param iniFile full file path
171      * @param encode specified encoding
172      * @return map of properteis content from the file
173      * @throws IOException IO about exception will throw out
174      */
175     public Map<String, String> loadFile(String iniFile, String encode) throws IOException {
176         if (iniFile == null) {
177             LOGGER.warn("null pointer of iniFile");
178             throw new NullPointerException("iniFile is set to be value of null");
179         }
180         if (iniFile.equals("")) {
181             throw new IOException("filename should not be null");
182         }
183         setIniFile(iniFile);
184 
185         File file = new File(iniFile);
186         if (!file.exists()) {
187             file.createNewFile();
188         }
189         fileTime = file.lastModified();
190         InputStream inFile = new FileInputStream(file);
191         return loadFile(inFile, encode);
192     }
193 
194     /**
195      * parse the format as ${..} variables
196      * @param field string to be parsed
197      * @return list object contains parsed variables
198      *         if field is null or blank null value will be return
199      */
200     private List<String> parseVaraibles(String field) {
201         List<String> variables = new ArrayList<String>();
202         
203         if (StringUtils.isBlank(field)) {
204             return null;
205         }
206         
207         int len = field.length();
208         char keyChar;
209         boolean iskey = false;
210         StringBuffer tempStr = new StringBuffer();
211         for (int i = 0; i < len; i++) {
212             keyChar = field.charAt(i);
213            
214             if (keyChar == '$') {
215                 if ((++< len) && (field.charAt(i) == '{')) {
216                     iskey = true;
217                     tempStr.setLength(0);
218                 }
219             } else if (keyChar == '}') {
220                 if (tempStr.length() > 0) {
221                     variables.add(tempStr.toString());
222                 }
223                 iskey = false;
224             } else {
225                 if (iskey) {
226                     tempStr.append(keyChar);
227                 }
228             }
229         }
230         
231         return variables;
232     }
233 
234     /**
235      * store the properties content to the opened file
236      * @throws IOException IO about exception will throw out
237      */
238     public void store() throws IOException {
239         this.store(this.iniFile);
240     }
241 
242     /**
243      * store the properties content to the specified file
244      * @param iniFile full file path
245      * @throws IOException IO about exception will throw out
246      */
247     public void store(String iniFile) throws IOException {
248         this.store(iniFile, null);
249     }
250 
251     /**
252      * store the properties content to the specified file
253      * and support to add comment
254      *    if call this method as follow:
255      *      store("c:\\test.ini", "Matthew update it");
256      * the comment will out like this:
257      *  #Matthew update it
258      *  #update time:2006-01-08 10:18:26
259      *  
260      * @param iniFile full file path
261      * @param comment comment for this updating
262      * @throws IOException IOException IO about exception will throw out
263      */
264     public void store(String iniFile, String comment) throws IOException {
265         if (iniFile == null) {
266             LOGGER.warn("null pointer of iniFile");
267             throw new NullPointerException("iniFile is set to be value of null");
268         }
269         if (iniFile.equals("")) {
270             throw new IOException("filename should not be null");
271         }
272 
273         if (this.propContent == null) {
274             return;
275         }
276 
277         StringBuffer sbuff = new StringBuffer();
278         if (comment != null && (!comment.equals(""))) {
279             sbuff.append("#");
280             sbuff.append(comment);
281             sbuff.append("\r\n");
282             DateFormat dformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
283             sbuff.append("#update time:").append(dformat.format(new Date()));
284             sbuff.append("\r\n");
285         }
286         
287         Iterator iter = this.propContent.entrySet().iterator();
288         String key, value;
289         while (iter.hasNext()) {
290             Map.Entry entry = (Map.Entry) iter.next();
291             key = (String) entry.getKey();
292             value = (String) entry.getValue();
293             
294             sbuff.append(key);
295             sbuff.append("=");
296             sbuff.append(value);
297             sbuff.append("\r\n");
298         }
299         
300         BufferedWriter wrf = new BufferedWriter(new FileWriter(iniFile, false));
301         wrf.write(sbuff.toString());
302         wrf.close();
303 
304     }
305 
306     /**
307      * get string properties value if the properties name not found null will be return
308      * @param key properties key
309      * @return properties value
310      */
311     public String getPropertiesValue(String key) {
312 
313         return getPropertiesValue(key, null);
314     }
315 
316     /**
317      * get string properties value if the properties name not found
318      *              default value will be return.
319      * @param key properties key
320      * @param defValue properties value
321      * @return properties value
322      */
323     public String getPropertiesValue(String key, String defValue) {
324         
325         if (isReloadOnchange) {
326             try {
327                 reloadOnChange();
328             } catch (IOException e) {
329                 LOGGER.warn("reload propeties file failed: reason:" + e.getMessage());
330             }
331         }
332 
333         String strRet = defValue;
334         if (key != null && (!key.equals(""))) {
335             strRet = this.propContent.get(key);
336             if (strRet == null) {
337                 return defValue;
338             }
339         }
340         return strRet;
341     }
342     
343     /**
344      * reload the properties file.
345      * 
346      * @throws IOException
347      */
348     private void reloadOnChange() throws IOException {
349         if (StringUtils.isBlank(iniFile)) {
350             return;
351         }
352 
353         File file = new File(iniFile);
354         if (!file.exists()) {
355             propContent.clear();
356             return;
357         }
358         
359         long fileLastModifytime = file.lastModified();
360         if (fileLastModifytime != fileTime) {
361             if (propContent != null) {
362                 propContent.clear();
363             }
364             if (LOGGER.isInfoEnabled()) {
365                 LOGGER.info("reloadOnChange() - reload ini file:" + iniFile);
366             }
367             loadFile(iniFile, defaultEncode);
368         }
369         
370     }
371 
372     /**
373      * get Integer properties value if the properties name not found
374      *                  default value will be return.
375      * @param key properties key
376      * @param defValue properties value
377      * @return properties value
378      */
379     public Integer getPropertiesInteger(String key, Integer defValue) {
380         int intRet = defValue;
381         String strValue = getPropertiesValue(key);
382         if (strValue != null) {
383             try {
384                 intRet = Integer.parseInt(strValue);
385             } catch (Exception e) {
386                 LOGGER.warn("parse String to Integer failed.");
387             }
388         }
389         return intRet;
390     }
391 
392     /**
393      * get Float properties value if the properties name not found
394      *                  default value will be return.
395      *                  
396      * @param key properties key
397      * @param defValue properties value
398      * @return properties value
399      */
400     public Float getPropertiesFloat(String key, Float defValue) {
401         float floatRet = defValue;
402         String strValue = getPropertiesValue(key);
403         if (strValue != null) {
404             try {
405                 floatRet = Float.parseFloat(strValue);
406             } catch (Exception e) {
407                 LOGGER.warn("parse String to Float failed.");
408             }
409         }
410         return floatRet;
411     }
412 
413     /**
414      * <p>
415      * set properties value. <code>null</code> value and key is not permitted.</p>
416      * @param key properties key
417      * @param value properties value
418      * @return return the previous value of the specified key 
419      *            in this property list, or null if it did not have one.
420      */
421     public Object setPropertiseValue(String key, String value) {
422         return this.propContent.put(key, value);
423     }
424     
425     /**
426      * set integer properties value
427      * @param key properties key
428      * @param value properties value
429      * @return return the previous value of the specified key 
430      *              in this property list, or null if it did not have one.
431      */
432     public Object setPropertiseValue(String key, Integer value) {
433         return this.propContent.put(key, value.toString());
434     }
435     
436     /**
437      * set float properties value
438      * @param key properties key
439      * @param value properties value
440      * @return return the previous value of the specified key 
441      *              in this property list, or null if it did not have one.
442      */
443     public Object setPropertiseValue(String key, Float value) {
444         return this.propContent.put(key, value.toString());
445     }
446 
447     /**
448      * <p>
449      * get all properties keys.<br>
450      * <code>null</code> will be return if the properties is <code>null</code>
451      * </p>
452      * @return list type properties keys
453      */
454     public List<String> getAllKeys() {
455         if (propContent == null) {
456             return null;
457         }
458         
459         Set<String> keys = propContent.keySet();
460         List<String> list = new LinkedList<String>(keys);
461         return list;
462     }
463 
464     /**
465      * <p>
466      * get all peroperties keys and values<br>
467      * <code>null</code> will be return if the properties is <code>null</code>
468      * </p>
469      * @return map type properties keys and values
470      */
471     public Map<String, String> getAllKeyValues() {
472         return propContent;
473     }
474     
475     /**
476      * @return the isReloadOnchange
477      */
478     public boolean isReloadOnchange() {
479         return isReloadOnchange;
480     }
481 
482     /**
483      * @param isReloadOnchange the isReloadOnchange to set
484      */
485     public void setReloadOnchange(boolean isReloadOnchange) {
486         this.isReloadOnchange = isReloadOnchange;
487     }
488 
489     /**
490      * @return the propContent
491      */
492     public Map<String, String> getPropContent() {
493         return propContent;
494     }
495 
496     /**
497      * @param propContent the propContent to set
498      */
499     public void setPropContent(Map<String, String> propContent) {
500         this.propContent = propContent;
501     }
502 
503     /**
504      * get the properties keys and values 
505      * @return override toString method. 
506      */
507     @Override
508     public String toString() {
509         StringBuffer sbuff = new StringBuffer();
510         sbuff.append("Properties values{");
511         if (this.propContent != null) {
512             Iterator iter = this.propContent.entrySet().iterator();
513             String key, value;
514             while (iter.hasNext()) {
515                 Map.Entry entry = (Map.Entry) iter.next();
516                 key = (String) entry.getKey();
517                 value = (String) entry.getValue();
518                 
519                 sbuff.append(key);
520                 sbuff.append("=");
521                 sbuff.append(value);
522                 sbuff.append("\r\n");
523             }       
524         }
525         sbuff.append("}");
526         return sbuff.toString();
527     }
528     
529 }

posted on 2008-04-13 12:18 x.matthew 阅读(5607) 评论(4)  编辑  收藏 所属分类: Best Practise(JDK API)

只有注册用户登录后才能发表评论。


网站导航: