Flask接口签名sign原理与实例代码浅析
520
2023-03-15
Java代码实现对properties文件有序的读写的示例
最近遇到一项需求,要求把properties文件中的内容读取出来供用户修改,修改完后需要再重新保存到properties文件中。很简单的需求吧,可问题是Properties是继承自HashTable的,直接通过keySet()、keys()或entrySet()方法对Properties中的元素进行遍历时取出来的内容顺序与properties文件中的顺序不一致,这是问题一;问题二是就算取出来的时候是有序的,保存到文件中时又是无序的了。
当然,解决这两个问题的方法有很多。我最终采用的方法是自定义一个PropertiesUtil类,该类继承自Properties。PropertiesUtil提供一个返回由key按照存入顺序组成的List的方法,getKeyList(),这样问题一就解决了。那如何保证getKeyList()方法返回的就是有序的key组成的集合呢?我查看了一下Properties方法的源码,发现其setProperty()方法实际上就是调用了父类HashTable的put()方法,其次Properties在从文件中加载内容时是按照文件顺序进行读取,然后调用父类HashTable的put()方法进行储存。所以问题的解决办法就是PropertiesUtil持有一个私有的可以有序存储key的集合,然后重写父类的put()方法,在方法体中照常通过super.put()进行属性的存储,同时将key添加到存储key的集合中。
Properties提供有save()方法和store()方法可以将当前对象的内容存放到指定的输出流中,但它们的底层逻辑都是一样的。通过调用keys()方法获取一个Enumeration,然后对该Enumeration进行遍历,依次将对应的key和value写入到输出流中,所以要保证写入是有序的,就要保证遍历keys()返回的Enumeration时取出的元素key是有序的。所以解决方法是重写keys()方法,保证遍历返回的Enumeration时得到的key是有序的。
下面就示范怎么按顺序读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
@Override
public Enumeration
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
Set
for (Object key : this.keys) {
set.add((String) key);
}
return set;
}
/**
* 因为复写了这个方法,在(方式二)的时候,才输出有序。
* {@link MainOrder#printProp}
*/
@Override
public Set
return keys;
}
//这个就不设置有序了,因为涉及到HashTable内部类:EntrySet,不好复写。
//public LinkedHashSet
// LinkedHashSet&http://lt;Map.Entry
// 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文件测试(带顺序的读和写)
*
* 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(http://"---------(方式二)------------");
Set
for (Object key : keys) {
System.out.println(key.toString() + "=" + properties.get(key));
}
System.out.println("---------(方式三)------------");
Set
for (Map.Entry
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.HAbBkEQudMgetMessage());
}
}
}
}
}
其实读和写,都和使用系统提供的类的差别不大,只是现在读到了我们自己写的子类里面去了。
其他的代码都是一样样的。
下面是读的文件的内容截图:
再然后是,实际代码运行的结果截图:
---------(方式一)------------
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
6HAbBkEQudM=66
7=77
8=88
9=99
10=18
11汉字=测试汉字以防乱码产生
额,太长了,就不截图了吧,就给把打印结果给展示一下得了。
可以看到,只有第三次是无序的,具体原因,我也在代码里面解释过了。
还有,就是生成的文件的截图:
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~