1.简单介绍
Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件,配置文件中很多变量是经常改变的,这样做也是为了方便用户,让用户能够脱离程序本身去修改相关的变量设置。像Python支持的配置文件是.ini文件,同样,它也有自己读取配置文件的类ConfigParse,方便程序员或用户通过该类的方法来修改.ini配置文件。在Java中,其配置文件常为.properties文件,格式为文本文件,文件的内容的格式是“键=值”的格式,文本注释信息可以用"#"来注释。
Properties类继承自Hashtable,如下:
它提供了几个主要的方法:
2.读取Properties文件
Java读取Properties文件的方法有很多,详细可参考:Java读取Properties文件的六种方法 常用的有两种:
通过java.lang.Class类的getResourceAsStream(String name)方法来实现
InputStream in = lnew BufferedInputStream(new FileInputStream(name)); Properties p = new Properties(); p.load(in);
使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法
InputStream in = JProperties.class.getClassLoader().getResourceAsStream(name); Properties p = new Properties(); p.load(in);
获取resource资源文件
InputStream stream = ClassLoader.getSystemResourceAsStream(fileName) String path = ClassLoader.getSystemResource(fileName).toURI().getPath()
3. 相关实例
下面介绍一些常用操作,方便加深对Properties的理解与记忆。 创建chan.properties
name=宁川 password=123456 [email protected]
读取properties
InputStream stream = ClassLoader.getSystemResourceAsStream(fileName); InputStreamReader reader = new InputStreamReader(stream, charsetName); properties.load(reader); String email = properties.getProperty("email");
关于中文的问题: 上面可以看到,我们的name是中文,这是我们打印出来的值可能是乱码的。 name=å®å·
这时,我们首先要保证使用的IDEproperties编码时UTF-8。 IDEA:文件->设置->编辑器->文件编码 eclipse:右键该文件->properties
然后可以在读取的时候指定编码,或者读取后再转换编码。 同样,保存的时候也指定UTF-8.
InputStream stream = ClassLoader.getSystemResourceAsStream(fileName); InputStreamReader reader = new InputStreamReader(stream, charsetName); properties.load(stream); String name; name = new String(properties.getProperty("name", "小明").toString().getBytes(),"UTF-8");
关于Properties顺序读写的问题:
Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。 总有时候会有关心顺序一致的需求,恰如有 org.apache.commons.collections.OrderdMap(其实用 LinkedHashMap 就是保证顺序)一样,我们也想要有个 OrderdProperties。
import java.util.*; public class OrderedProperties extends Properties { private static final long serialVersionUID = -4627607243846121965L; private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>(); @Override public synchronized Enumeration<Object> keys() { return Collections.<Object>enumeration(keys); } @Override public synchronized Object put(Object key, Object value) { keys.add(key); System.out.println("key=" + key); System.out.println("value=" + value); return super.put(key, value); } @Override public synchronized Object remove(Object key) { keys.remove(key); return super.remove(key); } @Override public Set<Object> keySet() { return keys; } @Override public Set<String> stringPropertyNames() { Set<String> set = new LinkedHashSet<String>(); for (Object key : this.keys) { set.add((String) key); } return set; } }
练习用的PropertiesUtils,包含一些常用操作。
import java.io.*; import java.util.*; public class PropertiesUtils { private Properties properties; private String fileName; private String charsetName = "UTF-8"; private Boolean autoCommit = true; public PropertiesUtils(String name) { loadProperties(name); } public PropertiesUtils(String name, String charsetName) { this.charsetName = charsetName; loadProperties(name); } public Properties getProperties() { return properties; } public void setCharsetName(String charsetName) { this.charsetName = charsetName; } public String getCharsetName() { return charsetName; } public void setAutoCommit(Boolean autoCommit) { this.autoCommit = autoCommit; } public Boolean getAutoCommit() { return autoCommit; } /** * 加载properties * @param name 资源文件properties * @return */ void loadProperties(String name) { fileName = name; InputStream stream = null; properties = new OrderedProperties(); try { stream = ClassLoader.getSystemResourceAsStream(fileName); InputStreamReader reader = new InputStreamReader(stream, charsetName); properties.load(reader); } catch (Exception e) { e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * properties转map * @return Map<String, String> */ public Map<String, String> getPropToMap() { Map<String, String> map = null; if (properties != null) { map = new HashMap<String, String>(); Enumeration enumeration = properties.propertyNames(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); String value = properties.getProperty(key); map.put(key, value); } } return map; } /** * 获取key对应的值 * @param key key * @return String */ public String getProperty(String key) { return getProperty(key, null); } /** * 获取key对应的值 * @param key key * @param defaultValue defaultValue * @return String */ public String getProperty(String key, String defaultValue) { if (properties != null && !properties.isEmpty()) { return properties.getProperty(key, defaultValue); } return null; } /** * 更新配置 * @param key key * @param value vale * @return Boolean */ public Boolean setProperty(String key, String value) { return setProperty(key, value, ""); } /** * 更新配置 * @param key key * @param value value * @param comments 说明 * @return Boolean */ public Boolean setProperty(String key, String value, String comments) { properties.setProperty(key, value); if (autoCommit) { return saveProperties(comments); } return true; } /** * 删除key * @param key key * @return Boolean */ public Boolean remove(String key) { return remove(key, ""); } /** * 删除key * @param key key * @param comments 说明 * @return Boolean */ public Boolean remove(String key, String comments) { properties.remove(key); if (autoCommit) { return saveProperties(comments); } return true; } /** * 保存Properties * @return Boolean */ public Boolean saveProperties() { return saveProperties(""); } /** * 保存Properties * @param comments 说明 * @return Boolean */ public Boolean saveProperties(String comments) { try { String path = ClassLoader.getSystemResource(fileName).toURI().getPath(); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(path), charsetName); properties.store(outputStreamWriter, comments); outputStreamWriter.close(); return true; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 打印properties */ public void toList() { Enumeration<Object> keys = properties.keys(); System.out.println("-- listing PropertiesUtils --"); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); System.out.println(String.format("%s=%s", key, getProperty(key))); } } }
测试:
public class PropertiesReader { public static void main(String[] args) { String fileName = "chan.properties"; PropertiesUtils propUtils = new PropertiesUtils(fileName); //查询key->value String key = "name"; String value = propUtils.getProperty(key); System.out.printf("%s=%s%n", key, value); System.out.println("--------------------------------"); //获取map Map<String, String> propMap = propUtils.getPropToMap(); propMap.forEach((k, v) -> System.out.println(String.format("%s=%s", k, v))); System.out.println("--------------------------------"); //更新值 propUtils.setProperty(key, "习惯"); System.out.println(propUtils.getProperty(key)); System.out.println("--------------------------------"); //新增值 propUtils.setProperty("hobby.one", "足球"); propUtils.setProperty("hobby.two", "football"); //删除 propUtils.remove("hobby.two"); //打印properties new PropertiesUtils(fileName).toList(); } }
继承Properties,并重写部分方法,经测试确实可以实现顺序读写。 OrderedProperties主要是通过Set保存properties的key,并重写有关peoperties key的方法,但是目前只是重写部分方法。 测试过程中发现,remove并保存的时候,出现空指针异常。经排查发现是key的问题,于是在网上找的方法的基础上,重写了remove方法。
由于还没看源码,可能还会有其他的问题,在这里记录一下。 但是目前常用操作都有了,也ok.
原文链接:https://www.cnblogs.com/sivanchan/p/13527079.html