java对【配置文件的读取】与【读配置文件时的路径问题】代码总结
相对通用的读文件流的方法(Windows 和 Linux上都可以用):add at 2014-03-21
拿到流,然后再去读流中的内容。
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(CONFIG_FILE_NAME);
package com.nos.path; import java.io.File; import java.net.URISyntaxException; public class PathGetTool { /*得到当前类的编译路径*/ public static String getCurrentClassPath(Class clazz){ String path = ""; try { File file = new File(clazz.getResource("").toURI()); path = file.getAbsolutePath(); }catch (URISyntaxException e){ e.printStackTrace(); } return path; } /*得到java文件编译后的classes目录。 * 注: * 1、web工程与java工程会有不同 * 在eclipse中web工程中的java源文件编译后会放在build\classes下面, * 而一般的java项目则会直接将编译后的java源文件放在bin目录下 * 2、web工程发布后,在eclipse中调用此方法,与在页面上调用执行此方法得到的编译路径会有不同 * 在eclipse中执行此方法时返回的是eclipse工程的编译路径build\classes * 而在页面上调用此方法时,返回的是工程发布后的类编译路径WEB-INF\classes * 总结: * 这主要是看运行的环境,eclipse中调用执行,当然是返回eclipse中的类编译路径。 * 当启了服务,在页面上调用执行时,是在tomcat环境下,返回的自然是工程发布后的编译路径*/ public static String getClassesPath(){ String path = ""; path = PathGetTool.class.getResource("/").toString(); if(path.startsWith("file")){ // 当class文件在class文件中时,返回"file:/F:/ ..."样的路径 path = path.substring(6); }else if(path.startsWith("jar")){ // 当class文件在jar文件中时,返回"jar:file:/F:/ ..."样的路径 path = path.substring(10); } if(path.endsWith("/") || path.endsWith("\\")){ //使返回的路径不包含最后的"/" path = path.substring(0, path.length()-1); } return path; } public static String getClassesPath2(){ String path = ""; try { File file = new File(PathGetTool.class.getResource("/").toURI()); path = file.getAbsolutePath(); }catch (URISyntaxException e){ e.printStackTrace(); } return path; } /*此方法只能对web项目在服务器开启的情况下,在页面上调用时才有用。 *因为只有这样getClassesPath2才能得到工程发布目录下的类编译路径(在WEB-INF\classes下) *如果是普通的java工程,则只会返回类文件的编译路径*/ public static String getWebRootPath(){ String path = ""; path = getClassesPath2().split("WEB-INF")[0]; if(path.endsWith("/") || path.endsWith("\\")){ //使返回的路径不包含最后的"/"或"\" path = path.substring(0, path.length()-1); } return path; } public static void main(String[] args) { // System.out.println(getCurrentProjectPath()); // System.out.println(getClassesPath()); // System.out.println(getClassesPath2()); // System.out.println(getWebRootPath()); // System.out.println(PathGetTool.class.getResource("")); // System.out.println(PathGetTool.class.getResource("/")); System.out.println("getCurrentClassPath="+getCurrentClassPath(PathGetTool.class)); } }
package com.nos.property; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; import com.nos.path.PathGetTool; public class PropertyTool { /*##############################################################################*/ /*###*****使用java.util.ResourceBundle类的getBundle()方法来读取properties配置文件******###*/ /*##############################################################################*/ /** * 功能:通过路径来得到ResourceBundle对象 */ public static ResourceBundle getBundleByPath(String path){ return ResourceBundle.getBundle(path); } /* 这里我们可以利用Locale和ResourceBundle的这个组合创建国际化的java程序。 * 我们可以把locale实例化为new Locale("zh","CN"); 通过ResourceBundle.getBundle("MessagesBundle", locale); 系统将自动寻找MessagesBundle_zh_CN,即定义为中国大陆地区简体中文。(下划线和后面的"zh、CN"表示的是本地化信息。) 如果没有该文件,则会依次寻找MessagesBundle_zh,MessagesBundle,直到找到为止。 只需要告诉ResourceBundle文件名是"property"就足够了,后缀properties是默认的。 */ /** * 功能:通过路径和本地化信息来得到ResourceBundle对象 */ public static ResourceBundle getBundleByPathAndLocale(String path, Locale locale){ return ResourceBundle.getBundle(path, locale); } /** * 功能:使用ResourceBundle,根据路径来读取配置文件,并将其键的集合返回 */ public static Enumeration getKeys(String path){ return PropertyTool.getBundleByPath(path).getKeys(); } public static List<String> getValues(String path){ ResourceBundle rb = PropertyTool.getBundleByPath(path); Enumeration keys = PropertyTool.getKeys(path); List<String> valueslist = new ArrayList(); while(keys.hasMoreElements()){ valueslist.add(rb.getString(keys.nextElement().toString())); } return valueslist; } /*##############################################################################*/ /*#######*****使用java.util.Properties类的load()方法来读取properties配置文件******########*/ /*##############################################################################*/ /**功能:得到java.util.Properties类的load(InputStream in)方法中所需要的InputStream * filename是编译路径下的配置文件名,是要包含类路径的文件名。 * 例如:如果data.properties放在com.nos包下,下面5种方法得到InputStream时传入的路径会略有不同 */ public static InputStream getPropertiesInputStream(String filename){ InputStream in = null; try{ //① 这个路径要使用全路径,就是在com/nos/data.properties前面加上类编译路径的根目录。比如现在的路径为:E:/workspace/test/bin/com/nos/data.properties // in = new BufferedInputStream(new FileInputStream(filename)); //② 这个filename也需要使用全路径 // in = new FileInputStream(filename); //③ 这个filename要使用相对路径,即在路径前面还要加一个斜杠。比如现在传过来的路径应该为:/com/nos/data.properties // in = PropertyTool.class.getResourceAsStream(filename); //④ 传入的filename应该是com/nos/data.properties // in = PropertyTool.class.getClassLoader().getResourceAsStream(filename); //⑤ 传入的filename应该是com/nos/data.properties in = ClassLoader.getSystemResourceAsStream(filename); }catch (Exception e){ e.printStackTrace(); } return in; } /** * 功能:通过java.util.Properties类的load方法装载properties,再使用propertyNames()来得到键key的集合 */ public static Enumeration getPropertiesNames(String filename){ Properties prop = new Properties(); try{ prop.load(PropertyTool.getPropertiesInputStream(filename)); }catch (IOException e){ e.printStackTrace(); } return prop.propertyNames(); } /** * 功能:通过java.util.Properties类的load方法装载properties来得到键key的集合, * 再通过prop.getProperty(key)来得到值 */ public static List<String> getPropertiesValues(String filename){ List<String> valueslist = new ArrayList(); Properties prop = new Properties(); try{ prop.load(PropertyTool.getPropertiesInputStream(filename)); Enumeration keysEnum = prop.propertyNames(); while(keysEnum.hasMoreElements()){ valueslist.add(prop.getProperty(keysEnum.nextElement().toString())); } }catch (IOException e){ e.printStackTrace(); } return valueslist; } /*##############################################################################*/ /*##############################*****公共部分******################################*/ /*##############################################################################*/ /*【原理解释】 我们用 API操作properties文件,如果获取的属性值是中文,为什么会出现乱码呢? 我们知道,如果编码(输出)和解码(读入)用的encoding是不一致的有可能会引起中文乱码问题,如果这两种encoding冲突,则你基本上就中奖了。 1、假设如果我们创建properties文件用的encoding是GBK,我们写入了中文 2、Properties文件默认机制是采用ISO8859-1处理 3、我们用Properties.getProperty(String key)接口读取内容,这是时候得到的是乱码。因为想用ISO8859-1对GBK编码的内容进行解码 4、我们把用Properties.getProperty(String key)接口读取内容转换为创建properties文件时用的encoding(GBK)不就解决问题了 */ /** * 功能:对于读含有中文的配置文件的时候进行编码转换,防止其乱码 */ public static String codeChange(String str){ try{ str = new String(str.getBytes("ISO8859-1"), System.getProperty("file.encoding")); }catch (UnsupportedEncodingException e){ e.printStackTrace(); } return str; } public static void main(String[] args) { // String path = "com.nos.data"; // Enumeration keysEnum = PropertyTool.getKeys(path); // List<String> valueslist = PropertyTool.getValues(path); // while(keysEnum.hasMoreElements()){ // System.out.println(PropertyTool.codeChange(keysEnum.nextElement().toString())); // } // for(int i=0; i<valueslist.size(); i++){ // System.out.println(valueslist.get(i)); // } String filename = "com/nos/data.properties"; //filename = PathGetTool.getClassesPath() + "/com/nos/data.properties"; System.out.println(filename); Enumeration keysEnum = PropertyTool.getPropertiesNames(filename); List<String> valueslist = PropertyTool.getPropertiesValues(filename); while(keysEnum.hasMoreElements()){ System.out.println(PropertyTool.codeChange(keysEnum.nextElement().toString())); } for(int i=0; i<valueslist.size(); i++){ System.out.println(valueslist.get(i)); } } }
2012-12-22今天发现ResourceBoundle可以直接读unicode码然后显示出中文,之前一直都为配置文件中的乱码而头痛,才有了上面的代码总结。现在可以直接将中文转为unicode存储在配置文件中了,使用如下代码读取:
ResourceBundle rb = ResourceBundle.getBundle("com.nos.data",Locale.CHINA);
System.err.println("info="+rb.getString("info"));
data.properties中存储的为:info=\u4e0b\u73ed\u4e86
打出的结果为:info=下班了