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=下班了

posted on 2012-09-03 16:34  快鸟  阅读(1826)  评论(0编辑  收藏  举报