前几天,公司项目中有一个需求是读取配置文件的,而且最好能够保证加载到内存中的顺序能够和配置文件中的顺序一致,但是,如果使用 jdk 中提供的 Properties 类的话,读取配置文件后,加载到内存中的顺序是随机的,不能保证和原文件的顺序一致,因此,jdk 提供的 Properties 是不行的。

由于有这样的需求,而 Java 的 Properties 类又不能实现,因此只能想别的办法。我曾经想过,在把配置文件加载到内存后,对其进行排序,但这个方案会有很多限制,而且也有问题。配置文件中的信息会有很多,如果对其进行再排序的话,首先会影响系统的性能,其次,对程序的执行效率来讲,也会有一定的影响。最后,经过一番查证之后,同事找到了一篇类似的文章。

解决方案

从文章中了解到,Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。

文章中已经给提供了代码,思路是继承自 Properties,覆盖原来的 put/keys,keySet,stringPropertyNames 即可,其中用一个 LinkedHashSet 来保存它的所有 key。完整代码如下:

import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.Set; /**
* OrderedProperties
* @author hanwl
* @date 2018-11-13
* @userd 使得Properties有序
*/
public class OrderedProperties extends Properties { private static final long serialVersionUID = 4710927773256743817L; private final LinkedHashSet<Object> keys = new LinkedHashSet<Object>(); @Override
public Enumeration<Object> keys() {
return Collections.<Object> enumeration(keys);
} @Override
public Object put(Object key, Object value) {
keys.add(key);
return super.put(key, value);
} @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;
}
}

调用方法:

public class demo {
Properties prop = new OrderedProperties();
File appDir = GlobalVars.getLocalAppDataDir();
File dir = new File(appDir, "userHistory/");
if (!dir.exists()) {
dir.mkdirs();
}
try {
OutputStreamWriter oStreamWriter = new OutputStreamWriter(new FileOutputStream(dir+"\\user.properties",true), "utf-8");
//FileOutputStream fileOutputstream = new FileOutputStream(dir+"\\user.properties", false);
prop.setProperty("serverUrl", serverUrlTextField.getText());
prop.setProperty("userName", userNameTextField.getText());
prop.setProperty("password", passwordField.getText());
prop.store(oStreamWriter, null);
oStreamWriter.close(); } catch (Exception e) {
e.printStackTrace();
} Properties prop = new OrderedProperties();
File appDir = GlobalVars.getLocalAppDataDir();
File dir = new File(appDir, "userHistory/");
if(new File(dir+"\\user.properties").exists()){
try {
InputStreamReader iStreamReader = new InputStreamReader(new FileInputStream(dir+"\\user.properties"),"utf-8");
prop.load(iStreamReader);
Iterator<String> it = prop.stringPropertyNames().iterator();
while (it.hasNext()) {
String key = it.next();
String value = prop.getProperty(key);
System.out.println(key+":"+value);
}
iStreamReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
    /**
* 返回程序本地数据存储目录
* C:\Users\Administrator\AppData\Local\Founder\PublisherClient
* C:\Users\Administrator\AppData\Local\Founder\PrinterClient
* C:\Users\Administrator\AppData\Local\Founder\TypeSettingClient
* @return
*/
public static File getLocalAppDataDir() {
String appDataPath;
if (Util.isMac()) {
appDataPath = System.getProperty("user.home") + "/Library/";
}
else if (NativeUtil.libraryLoaded()) {
appDataPath = NativeUtil.getLocalAppDataFolder();
}
else {
appDataPath = System.getProperty("user.home");
} File founderDir = new File(appDataPath, Util.isWindows() || Util.isMac() ? "Founder" : ".Founder");
File appDir = new File(founderDir, CLIENT_TYPE.getClientName());
appDir.mkdirs(); return appDir;
}
结束
 
  这种特定的需求,以前倒是没怎么接触过,不给通过这次的经历,发现了一点,自己的积累还是很少,不多说了,继续努力吧。
 
参考:

 

Java Properties 类读配置文件保持顺序的更多相关文章

  1. java properties类读取配置文件

    1.JAVA Properties类,在java.util包里,具体类是java.util.properties.Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值 ...

  2. java工具类-读配置文件

    ///读配置文件 import java.io.InputStream;import java.util.HashMap;import java.util.Map;import java.util.M ...

  3. Java 数据类型:集合接口Map:HashTable;HashMap;IdentityHashMap;LinkedHashMap;Properties类读取配置文件;SortedMap接口和TreeMap实现类:【线程安全的ConcurrentHashMap】

    Map集合java.util.Map Map用于保存具有映射关系的数据,因此Map集合里保存着两个值,一个是用于保存Map里的key,另外一组值用于保存Map里的value.key和value都可以是 ...

  4. 基于Java Properties类设置本地配置文件

    一.Java Properties类介绍 Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件, ...

  5. 读配置文件能够保持顺序的 Java Properties 类

    序 前几天,公司项目中有一个需求是读取配置文件的.并且最好可以保证载入到内存中的顺序可以和配置文件里的顺序一致,可是.假设使用 jdk 中提供的 Properties 类的话,读取配置文件后.载入到内 ...

  6. 使用java.util.Properties类读写配置文件

    J2SE 1.5 以前的版本要求直接使用 XML 解析器来装载配置文件并存储设置,虽说也并非难事,相比 java.util.Properties却要做额外的解析工作.而java.util.Proper ...

  7. day1 java基础回顾- Properties类与配置文件

    Properties配置文件说明 Properties类对应.properties文件.文件内容是键值对,键值对之间使用"="或空格隔开.开头是"#"的表示注释 ...

  8. 【JAVA Properties类概述】

    一.概述. 之前说过,该对象是和IO流相结合的技术,所以和IO流结合在一起来讲比较合适. public class Propertiesextends Hashtable<Object,Obje ...

  9. Java Properties类源码分析

    一.Properties类介绍 java.util.Properties继承自java.util.Hashtable,从jdk1.1版本开始,Properties的实现基本上就没有什么大的变动.从ht ...

随机推荐

  1. js获取时间相关函数

    js获取时间函数 var myDate = new Date; var year = myDate.getFullYear();//获取当前年 var yue = myDate.getMonth()+ ...

  2. Flafka: Apache Flume Meets Apache Kafka for Event Processing

    The new integration between Flume and Kafka offers sub-second-latency event processing without the n ...

  3. Python学习--Python运算符

    什么是运算符? 举个简单的例子 4 + 5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算符: 算数运算符 比较(关系)运算 ...

  4. Linux内存管理 (23)一个内存Oops解析

    专题:Linux内存管理专题 关键词:DataAbort.fsr.pte.backtrace.stack.   在内存相关实际应用中,内存异常访问是一种常见的问题. 本文结合异常T32栈回溯.Oops ...

  5. left join inner join 区别

    left 以左表为准,左表在右表没有对应的记录,也为显示(右表字段填空). inner 需要满足两张表都有记录. 不管哪种join 一对多最终的结局 只会是多条记录

  6. 乡下人重拾MVC——@RenderBody @RenderSection @Html.Partial @Html.Action @Html.RenderPartial @Html.RenderAction

    1.   @RenderBody()  代表:是一个占位符,是留给子页面的位置,子页面使用这个模版,子页面中的内容会被放到@RenderBody的位置.合并后当作一个整体加载 2.   @Render ...

  7. hbase集群搭建参考资料

    hadoop分布式集群搭建 http://www.ityouknow.com/hadoop/2017/07/24/hadoop-cluster-setup.html hbase分布式集群搭建: htt ...

  8. docker 搭建 Telegram Messenger MTP

    docker hub官方镜像地址如下: https://hub.docker.com/r/telegrammessenger/proxy 拉取镜像 sudo docker pull telegramm ...

  9. MySQL数据类型的选择

    +++++++++++++++++++++++++++++++++++++++++++标题:MySQL数据类型的选择时间:2019年2月22日内容:MySQL数据类型的选择范式参考重点:主要讲述MyS ...

  10. Null value was assigned to a property of primitive type setter of com.oa.manager.personnel.bean.KqAttendanceHoliday.dayType

    问题: 解决方法:依据提示,把 int 修改为Integer解决. 总结: javaBean最好不要使用基本类型(记得某规范说过,具体不记得了,估计就是预防这样的问题吧)