<导航

Properties读取properties文件

  今天就先从网上摘写总结下这个基础类,后续再加上实战总结补充进来,所以排版可能比较乱。。

  在编写一个项目时,我们会时常修改一些配置变量来适应不同的运行环境,同时也让用户能够脱离程序去修改相关的变量设置。通常我们将这些变量定义在后缀名为properties的文件中,文件内容的格式为“键=值”,文本用“#”注释。

  而java提供了java.util.Properties来读取这些文件,它提供了几个主要的方法:

  • getProperty ( String key),用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。
  • load ( InputStream inStream),从输入流中读取属性列表(键和元素对)。通过对指定的文件(比如说上面的 test.properties 文件)进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。
  • setProperty ( String key, String value) ,调用 Hashtable 的方法 put 。他通过调用基类的put方法来设置 键 - 值对。
  • store ( OutputStream out, String comments),以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。与 load 方法相反,该方法将键 - 值对写入到指定的文件中去。
  • clear (),清除所有装载的 键 - 值对。该方法在基类中提供。
要获取定义在.properties中的值,首先要用Properties的方法load(InputStream inStream)来装载配置文件从而获取配置文件中的键值对,形成属性列表,其次用getProperty(String key)来获取属性列表中对应的值。

jdbc.properties:

driverClass = com.mysql.jdbc.Driver  
jdbcURL=jdbc:mysql://127.0.0.1:3306/protest?useUnicode=true&characterEncoding=utf-8   
user = root  
password = root  

使用FileInputStream("资源名称绝对路径")

public Properties propertiesFromFile() throws FileNotFoundException{  
        properties = new Properties();  
        InputStream in = null;  
        try{  
            in = new BufferedInputStream(new FileInputStream(propertiesPath));  
            properties.load(in);  
        }catch (FileNotFoundException e){  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally{  
            try {  
                in.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        return properties;  
    }  

使用getClass.getResourceAsStream("资源名称") -推荐

public Properties propertiesFromClass(){  
    properties = new Properties();  
    InputStream in1 = this.getClass().getResourceAsStream(propertiesPath);  
    InputStream is=PropertiesLoad.class.getResourceAsStream("/jdbc.properties");  
    try {  
        properties.load(in1);  
    } catch (IOException e) {  
        e.printStackTrace();  
    }finally{  
        try {  
            in1.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
    return properties;  
}  

最后使用getProperty(key)获取properties中的值:

PropertiesLoad proLoad = new PropertiesLoad(propertiesPath);  
String DriverClass = proLoad.propertiesFromClass().getProperty("driverClass"); 

对于在程序中对properties文件的修改:

PropertiesLoad proLoad = new PropertiesLoad(propertiesPath);  
Properties pro = proLoad.propertiesFromClass();  
OutputStream out = new FileOutputStream(DBconnect.class.getResource("/jdbc1.properties").toString().substring(6));  
pro.setProperty("password", password+"1");  
try {  
     pro.store(out, "ceshiwenjian01");  
     } catch (IOException e) {  
    e.printStackTrace();  
     }  
结果 jdbc1.properties:
#ceshiwenjian01  
#Tue Aug 30 16:06:07 GMT+08:00 2016  
driverClass=com.mysql.jdbc.Driver  
user=root  
password=root1  
jdbcURL=jdbc\:mysql\://127.0.0.1\:3306/protest?useUnicode\=true&characterEncoding\=utf-8   

  在上述的例子中,如果将Properties pro = proLoad.propertiesFromClass();换成Properties pro = new Properties();那么最后jdbc1.properties中的键值对只剩下password。所以所谓的setProperties(key,value)是将键值对写放入pro中,然后pro通过store将所有的pro里的键值对写入到文件中。上例中最后呈现的结果类似于改变键值对的值是因为pro装载了原来的键值对。

注:
  在我们知道如何读写一个属性文件之后,我们仍然还有很多需要注意的问题,因为load和store方法都是按照ISO-8859-1的编码方式读写属性流文件的,而ILatin1 的字符和某些特殊字符,而对于非Latin1 的字符和某些特殊字符,则要使用与字符和字符串字面值所用的类似转义序列,以值和元素的形式来表示它们。所以当我们在处理中文时,不可以在直接修改属性文件时,将中文的值赋予给属性,而是要在JAVA程序中通过setProperty方法给属性赋予中文的值,因为这样store会将中文转换成 unicode码,在读取时系统会将读取到的unicode码按系统的编码打印出来,对于中文系统,通常是GBK码,这样中文才能够正常显示。

我们知道,Java虚拟机(JVM)有自己的系统配置文件(system.properties),我们可以通过下面的方式来获取。

相关实例

1、获取JVM的系统属性

import java.util.Properties;

public class ReadJVM {
    public static void main(String[] args) {
        Properties pps = System.getProperties();
        pps.list(System.out);
    }
}

 结果:

2、一个比较综合的实例

//关于Properties类常用的操作
public class TestProperties {
    //根据Key读取Value
    public static String GetValueByKey(String filePath, String key) {
        Properties pps = new Properties();
        try {
            InputStream in = new BufferedInputStream (new FileInputStream(filePath));  
            pps.load(in);
            String value = pps.getProperty(key);
            System.out.println(key + " = " + value);
            return value;
            
        }catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    //读取Properties的全部信息
    public static void GetAllProperties(String filePath) throws IOException {
        Properties pps = new Properties();
        InputStream in = new BufferedInputStream(new FileInputStream(filePath));
        pps.load(in);
        Enumeration en = pps.propertyNames(); //得到配置文件的名字
        
        while(en.hasMoreElements()) {
            String strKey = (String) en.nextElement();
            String strValue = pps.getProperty(strKey);
            System.out.println(strKey + "=" + strValue);
        }
        
    }
    
    //写入Properties信息
    public static void WriteProperties (String filePath, String pKey, String pValue) throws IOException {
        Properties pps = new Properties();
        
        InputStream in = new FileInputStream(filePath);
        //从输入流中读取属性列表(键和元素对) 
        pps.load(in);
        //调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。  
        //强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
        OutputStream out = new FileOutputStream(filePath);
        pps.setProperty(pKey, pValue);
        //以适合使用 load 方法加载到 Properties 表中的格式,  
        //将此 Properties 表中的属性列表(键和元素对)写入输出流  
        pps.store(out, "Update " + pKey + " name");
    }
    
    public static void main(String [] args) throws IOException{
        //String value = GetValueByKey("Test.properties", "name");
        //System.out.println(value);
        //GetAllProperties("Test.properties");
        WriteProperties("Test.properties","long", "212");
    }
}

结果:
Test.properties中文件的数据为:

#Update long name
#Sun Feb 23 18:17:16 CST 2014
name=JJ
Weight=4444
long=212
Height=3333

3、附例

属性文件a.properties 
name=root
pass=liu
key=value

读取a.properties属性列表,与生成属性文件b.properties。代码如下:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream; 
import java.util.Iterator;
import java.util.Properties; 

public class PropertyTest {
    public static void main(String[] args) { 
        Properties prop = new Properties();     
        try{
            //读取属性文件a.properties
            InputStream in = new BufferedInputStream (new FileInputStream("a.properties"));
            prop.load(in);     ///加载属性列表
            Iterator<String> it=prop.stringPropertyNames().iterator();
            while(it.hasNext()){
                String key=it.next();
                System.out.println(key+":"+prop.getProperty(key));
            }
            in.close();
            
            ///保存属性到b.properties文件
            FileOutputStream oFile = new FileOutputStream("b.properties", true);//true表示追加打开
            prop.setProperty("phone", "10086");
            prop.store(oFile, "The New properties file");
            oFile.close();
        }
        catch(Exception e){
            System.out.println(e);
        }
    } 
}

项目中读取资源配置文件的方法

项目结构如图,ReadProperties.java为读取资源文件主要方法: 

前提:使用 InputStream 进行读取时,需注意关闭流!!

相同代码部分:

Properties prop=new Properties();

InputStream ins=null;

try{

  ins....... // 代码变更部分

  prop.load(ins);

  String resultStr=prop.getProperty("param1");

}catch(Exception e){

  e.printStackTrace();

}finally{

  if(null!=ins){

    try{

      ins.close();

    }catch(IOException e){

      e.printStackTrace();

    }    

  }

}

代码变更部分:

1、读取myPro1.properties,读取和类文件同一目录下的资源文件:

  ins=ReadProperties.class.getResourceAsStream("myPro1.properties");// 不用 getClassLoader() 来获取getResourceAsStream(),这是获取同一路径下的资源文件

2、读取myPro2.properties,读取另一文件夹下的资源文件:

  ins=ReadProperties.class.getClassLoader().getResourceAsStream("config/myPro2.properties");// 写资源文件所在的路径

3、读取myPro3.properties,读取src根目录下的资源文件:

  ins=ReadProperties.class.getClassLoader().getResourceAsStream("myPro3.properties");// 只写资源文件名称即可

4、读取myPro4.properties,读取另一资源包下的资源文件

  ins=ReadProperties.class.getClassLoader().getResourceAsStream("myPro4.properties");//  只写文件名即可;如果是configFolder/myPro4.properties,则报null异常

5、读取myPro5.properties,读取另一包下的资源文件

  ins=ReadProperties.class.getClassLoader().getResourceAsStream("com/test/myPro5.properties"); // 资源文件所在路径,如果只写资源文件名称,报null异常

总结:

 1、获取和类文件处于相同路径下的资源文件使用 ReadProperties.class.getResourceAsStream("myPro1.properties")来获取,不用.class.getClassLoader()

 2、获取其它包或不同包下的文件夹下的配置文件,使用ReadProperties.class.getClassLoader().getResourceAsStream("config/myPro2.properties")来获取,参数是该资源文件所在的相对路径

 3、获取src根目录或另一资源文件夹的根目录下的资源文件,使用ReadProperties.class.getClassLoader().getResourceAsStream("myPro2.properties")  参数只写资源文件名称即可。

 

 

文章整理自:

https://blog.csdn.net/l18848956739/article/details/79518911

https://www.cnblogs.com/changzhichen/p/5099880.html

https://www.cnblogs.com/bakari/p/3562244.html

 

posted @ 2019-04-14 16:37  字节悦动  阅读(500)  评论(0编辑  收藏  举报