Java Properties文件读写设计-java读写文件

Java Properties文件读写设计-java读写文件

凡是中文乱码问题,都是字符读写的编码格式不统一的问题。

一般情况下,便于统一字符编码格式,所有文件读写格式均设为utf-8模式,这些地方包括数据库字符存储格式,源代码文件编码格式,资源文件编码格式,前端页面编码格式,网络IO流字符编码格式等。

鉴于以上前提,本文着重关心的是properties资源文件的读写。下面所展示的封装类功能包括:

(1)读取资源文件中的值(处理了同一个资源文件中资源值相互引用的问题)

(2)写资源文件

(3)处理了properties文件中中文字符读取乱码问题。

关于问题(1),例如对于具有以下内容的properties文件:在test1的值中通过自定义的语法${key}来引用同一文件中的其他键值。在处理过程中,先读取字符串test1的值,再通过正则表达式匹配出key值,再按key值读取test的值,并拼凑到test1中,从而得到最终的test1的值。

test=test

test1=${test}

关于问题2,重点在于如果便捷地根据文件名获取到文件输入流,采用的方式是通过类ClassLoader根据编译后相对于classpath的路径名,获取到文件的URL,再转化为URI,由于File函数的构造函数中,提供了以文件URI为输入参数的构造器,所以便可以直接通过这种方式获得File对象,进而获得对应资源文件的输入流。

需要指出的是,在以下两种获得文件URL的方式中,区别仅在于是否通过ClassLoader,其中方式1适用于任何Java项目环境下;而方式2则仅适用于Java Application,而在Java Web应用环境下,获取不到文件URL值。

//方式1

URL url = PropsUtil.class.getClassLoader().getResource("setting/token.properties");

//方式2

URL url = PropsUtil.class..getResource("setting/token.properties");

对于问题3,方便起见,首先需将对应properties文件设置为utf-8编码格式(在IDEA环境下,由file->setting->editor->file encodings设置),否则以unicode编码的话,不仅不便于文档的统一,而且里面的中文字符会自动转成Unicode格式,极其不直观。

通常获得Properties对象的方式是,通过文件ClassLoader(方式1)获得文件输入流,在调用properties.load(imputstream)的方式完成初始化,然而这种方式下,由于不能够指定读取资源文件时的字符编码格式,在读取中文字符时便会出现乱码。

所以,更好的做法是,将该inputstream作为构造参数包装成Reader类,并在构造器的另一个参数中指明采用utf-8的方式,再通过properties.load(reader),完成初始化,便可解决中文字符读取乱码问题。

类源码如下:

/**

* Created by Song on 2016/11/2.

* mail:1147649695@qq.com

* @since v0.0

*/

public final class PropsUtil {

private static final Pattern PATTERN = Pattern.compile("\\$\\{([^\\}]+)\\}");

/**

* 加载资源文件

* @param fileName 资源文件名

* @return

*/

public static Properties loadProps(String fileName){

Properties pros = null;

Reader reader = null;

try{

reader = new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName),"utf-8");

if(null == reader){

throw new FileNotFoundException(fileName+" file is not found");

}

pros = new Properties();

pros.load(reader);

}catch (IOException e){

System.err.println("load peoperties file failed");

e.printStackTrace();

}finally {

if(null != reader){

try {

reader.close();

}catch (IOException e){

System.err.println("close input stream failed");

e.printStackTrace();

}

}

}

return pros;

}

/**

* 获取资源文件值

* @param key 键名

* @param prop 资源文件句柄

* @return

*/

public static String getProperty(String key,Properties prop) {

String value = prop.getProperty(key);

Matcher matcher = PATTERN.matcher(value);

StringBuffer buffer = new StringBuffer();

while (matcher.find()) {

String matcherKey = matcher.group(1);

String matchervalue = prop.getProperty(matcherKey);

if (matchervalue != null) {

matcher.appendReplacement(buffer, matchervalue);

}

}

matcher.appendTail(buffer);

return buffer.toString();

}

/**

* 写资源文件

* 问题很奇怪,重新加载资源文件并读键值,可得到最新的值,然而直接打开文件,却读不到新值

* @param key

* @param value

* @param fileName

* @return

* @throws Exception

*/

public static boolean setProperty(String key,String value,String fileName) throws Exception{

URL url = PropsUtil.class.getClassLoader().getResource("setting/token.properties");

Properties properties = new Properties();

properties.setProperty(key, value);

properties.store(new FileOutputStream(new File(url.toURI())),"");

return true;

}

}

推荐阅读