Java代码实现对properties文件有序的读写

直接使用java.util.Properties提供的类,读取properties文件的时候,读出来的是乱序的。
但是,我想要的,或者开发需求是要求,怎么读进来,怎么写出去。按顺序读,还得按顺序写。
下面就示范怎么按顺序读properties文件,以及还得按原来的顺序写properties文件。

package com.lxk.propertyFileTest;

import java.util.*;

/**
 * Created by lxk on 2017/5/2
 */
public class OrderedProperties extends Properties {
    private static final long serialVersionUID = -4627607243846121965L;

    /**
     * 因为LinkedHashSet有序,所以,key在调用put()的时候,存放到这里也就有序。
     */
    private final LinkedHashSet<Object> keys = new LinkedHashSet<>();

    @Override
    public Enumeration<Object> keys() {
        return Collections.enumeration(keys);
    }

    /**
     * 在put的时候,只是把key有序的存到{@link OrderedProperties#keys}
     * 取值的时候,根据有序的keys,可以有序的取出所有value
     * 依然调用父类的put方法,也就是key value 键值对还是存在hashTable里.
     * 只是现在多了个存key的属性{@link OrderedProperties#keys}
     */
    @Override
    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }

    /**
     * 因为复写了这个方法,在(方式一)的时候,才输出有序。
     * {@link MainOrder#printProp}
     */
    @Override
    public Set<String> stringPropertyNames() {
        Set<String> set = new LinkedHashSet<>();
        for (Object key : this.keys) {
            set.add((String) key);
        }
        return set;
    }

    /**
     * 因为复写了这个方法,在(方式二)的时候,才输出有序。
     * {@link MainOrder#printProp}
     */
    @Override
    public Set<Object> keySet() {
        return keys;
    }

    //这个就不设置有序了,因为涉及到HashTable内部类:EntrySet,不好复写。
    //public LinkedHashSet<Map.Entry<Object, Object>> entrySet() {
    //    LinkedHashSet<Map.Entry<Object, Object>> entrySet = new LinkedHashSet<>();
    //    for (Object key : keys) {
    //
    //    }
    //    return entrySet;
    //}

    /**
     * 因为复写了这个方法,在(方式四)的时候,才输出有序。
     * {@link MainOrder#printProp}
     */
    @Override
    public Enumeration<?> propertyNames() {
        return Collections.enumeration(keys);
    }
}

上面是继承Java自带的类,我们做的主要是实现有序,其他的还是原来的样子就行。

看下整个的类继承关系:如下图:



下面是main方法的类。

package com.lxk.propertyFileTest;

import java.io.*;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * 读写properties文件测试(带顺序的读和写)
 * <p>
 * Created by lxk on 2017/5/2
 */
public class MainOrder {
    public static void main(String[] args) {
        Properties prop = readOrderedPropertiesFile();
        printProp(prop);
        writeOrderedPropertiesFile(prop);
    }

    /**
     * 输出properties的key和value
     */
    public static void printProp(Properties properties) {
        System.out.println("---------(方式一)------------");
        for (String key : properties.stringPropertyNames()) {
            System.out.println(key + "=" + properties.getProperty(key));
        }

        System.out.println("---------(方式二)------------");
        Set<Object> keys = properties.keySet();//返回属性key的集合
        for (Object key : keys) {
            System.out.println(key.toString() + "=" + properties.get(key));
        }

        System.out.println("---------(方式三)------------");
        Set<Map.Entry<Object, Object>> entrySet = properties.entrySet();//返回的属性键值对实体
        for (Map.Entry<Object, Object> entry : entrySet) {
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }

        System.out.println("---------(方式四)------------");
        Enumeration<?> e = properties.propertyNames();
        while (e.hasMoreElements()) {
            String key = (String) e.nextElement();
            String value = properties.getProperty(key);
            System.out.println(key + "=" + value);
        }
    }

    /**
     * 读Properties文件(有序)
     */
    private static Properties readOrderedPropertiesFile() {
        Properties properties = new OrderedProperties();
        InputStreamReader inputStreamReader = null;
        try {
            InputStream inputStream = new BufferedInputStream(new FileInputStream("D:testOrder.properties"));
            //prop.load(in);//直接这么写,如果properties文件中有汉子,则汉字会乱码。因为未设置编码格式。
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            properties.load(inputStreamReader);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        }
        return properties;
    }

    /**
     * 写Properties文件(有序)
     */
    private static void writeOrderedPropertiesFile(Properties properties) {
        properties.setProperty("phone", "10086");
        OutputStreamWriter outputStreamWriter = null;
        try {
            //保存属性到b.properties文件
            FileOutputStream fileOutputStream = new FileOutputStream("order.properties", false);//true表示追加打开,false每次都是清空再重写
            //prop.store(oFile, "此参数是保存生成properties文件中第一行的注释说明文字");//这个会两个地方乱码
            //prop.store(new OutputStreamWriter(oFile, "utf-8"), "汉字乱码");//这个就是生成的properties文件中第一行的注释文字乱码
            outputStreamWriter = new OutputStreamWriter(fileOutputStream, "utf-8");
            properties.store(outputStreamWriter, "lll");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            if (outputStreamWriter != null) {
                try {
                    outputStreamWriter.close();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
        }

    }
}

其实读和写,都和使用系统提供的类的差别不大,只是现在读到了我们自己写的子类里面去了。

起他的代码都是一样样的。


下面是读的文件的内容截图:



再然后是,实际代码运行的结果截图:

---------(方式一)------------
1=11
2=22
3=33
4=44
5=55
6=66
7=77
8=88
9=99
10=18
11汉字=测试汉字以防乱码产生
---------(方式二)------------
1=11
2=22
3=33
4=44
5=55
6=66
7=77
8=88
9=99
10=18
11汉字=测试汉字以防乱码产生
---------(方式三)------------
11汉字=测试汉字以防乱码产生
9=99
8=88
7=77
6=66
5=55
4=44
3=33
2=22
10=18
1=11
---------(方式四)------------
1=11
2=22
3=33
4=44
5=55
6=66
7=77
8=88
9=99
10=18
11汉字=测试汉字以防乱码产生


额,太长了,就不截图了吧,就给把打印结果给展示一下得了。

可以看到,只有第三次是无序的,具体原因,我也在代码里面解释过了。


还有,就是生成的文件的截图:


觉得此文有用的,不嫌麻烦的,就点个赞吧,要是嫌弃麻烦呢,也麻烦点个赞嘛,要是实在不想点赞呢,也不是不可以。
但是,你要是想踩一脚呢,那还是赶紧,马上,快快的闪人。

小心我手里三十米长的大刀。哼哼。想想都怕 !!!


©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值