一、properties文件
Properties文件是java中很常用的一種配置文件,文件后綴為“.properties”,屬文本文件,文件的內容格式是“鍵=值”的格式,可以用“#”作為注釋,java編程中用到的地方很多,運用配置文件,可以便於java深層次的解耦。例如java應用通過JDBC連接數據庫時,通常需要在代碼中寫數據庫連接字符串,下面貼出java通過JDBC連接數據庫的代碼(以mysql為例):
String driver="com.mysql.jdbc.Driver";//mysql提供的Driver接口的實現類
String jdbcUrl="jdbc:mysql:///user";//此處為"jdbc:mysql://localhost:3306/user"的簡化形式,user為數據庫名
String user="root";
String password="451535";
Class.forName(driver);//通過反射動態實例化mysql數據庫驅動類
Connection conn= DriverManager.getConnection(jdbcUrl,user,password);
1234567
以上代碼連接mysql數據庫沒有任何問題,但是我想換成Oracle數據庫,問題就來了,不是不能改,而是我必須得到java源代碼中修改代碼,這樣的硬代碼耦合在java中一般不這么做(菜鳥程序員有可能)。所以,為了達到解耦的目的,我們可以用配置文件來儲存數據庫的連接字符串。下面貼一份保存數據庫連接字符串的properties配置文件 jdbc.properties:
driver=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/user
user=root
password=451535
這樣我們就可以通過加載properties配置文件來連接數據庫,達到深層次的解耦目的,如果想要換成oracle或是DB2,我們只需要修改配置文件即可,不用修改任何代碼就可以更換數據庫。
二、Properties類
java中提供了配置文件的操作類Properties類(java.util.Properties):
public class Properties extends Hashtable.可見Properties類繼承了Hashtable,而HashTable又實現了Map接口,所以可對 Properties 對象應用 put 和 putAll 方法。但不建議使用這兩個方法,因為它們允許調用者插入其鍵或值不是 String 的項。相反,應該使用 setProperty 方法。如果在“不安全”的 Properties 對象(即包含非 String 的鍵或值)上調用 store 或 save 方法,則該調用將失敗。
Properties的常用方法:
1.setProperty(String key, String value)
調用 Hashtable 的方法 put。
2.
getProperty(String key)
用指定的鍵在此屬性列表中搜索屬性
3.
getProperty(String key, String defaultValue)
用指定的鍵在屬性列表中搜索屬性。
4.
load(InputStream inStream)
從輸入流中讀取屬性列表(鍵和元素對)。
5.
load(Reader reader)
按簡單的面向行的格式從輸入字符流中讀取屬性列表(鍵和元素對)。
6.
loadFromXML(InputStream in)
將指定輸入流中由 XML 文檔所表示的所有屬性加載到此屬性表中。
7.store(OutputStream out, String comments)
以適合使用 load(InputStream) 方法加載到 Properties 表中的格式,將此 Properties 表中的屬性列表(鍵和元素對)寫入輸出流。
8.store(Writer writer, String comments)
以適合使用 load(Reader) 方法的格式,將此 Properties 表中的屬性列表(鍵和元素對)寫入輸出字符。
9.storeToXML(OutputStream os, String comment)
發出一個表示此表中包含的所有屬性的 XML 文檔。
10.storeToXML(OutputStream os, String comment, String encoding)
使用指定的編碼發出一個表示此表中包含的所有屬性的 XML 文檔。
下面通過代碼的形式了解Properties的具體用法(通過JUnit單元測試的形式運行代碼):
*1.為properties對象添加屬性和獲取值*
@Test
public void setAndGetProperty() {
Properties pro=new Properties();
//設置值
pro.setProperty("driver", "com.mysql.jdbc.Driver");
pro.setProperty("url", "jdbc:mysql///user");
pro.setProperty("user", "root");
pro.setProperty("password", "451535");
//獲取值:
//1、getProperty(String key)方法 通過鍵獲取值
String str= pro.getProperty("driver");
System.out.println(str);
//2、getProperty(String key, String defaultValue)重載方法
//當properties對象中沒有所指定的鍵值時,顯示給定的默認值
String str2=pro.getProperty("driver", "沒有該值");
String str3=pro.getProperty("haha", "沒有該值");
System.out.println(str2);
System.out.println(str3);
}
123456789101112131415161718192021
運行結果:
com.mysql.jdbc.Driver
com.mysql.jdbc.Driver
沒有該值
*2.以properties配置文件格式寫入到硬盤中的某個文件夾(本例寫入到D盤的others文件夾中):*
@Test
public void storePropertiesToHardFile() throws FileNotFoundException, IOException{
Properties pro=new Properties();
pro.setProperty("driver", "com.mysql.jdbc.Driver");
pro.setProperty("url", "jdbc:mysql///user");
pro.setProperty("user", "root");
pro.setProperty("password", "451535");
//1.通過字節流的形式
//store(OutputStream out, String comments)
//outputStream:字節輸出流 comments:配置文件說明
pro.store(new FileOutputStream(new File("d:/others/jdbc.properties")), "數據庫配置文件");
//2.通過字符流的形式
//store(Writer writer, String comments)
//writer:字符輸出流 comments:配置文件說明
pro.store(new FileWriter("d:/others/jdbc.properties"), "數據庫配置文件");
}
123456789101112131415161718
運行后效果:
*3.以XML配置文件格式寫入到硬盤中的某個文件夾(本例寫入到D盤的others文件夾中):*
@Test
public void storeXMLToHardFile() throws FileNotFoundException, IOException{
Properties pro=new Properties();
pro.setProperty("driver", "com.mysql.jdbc.Driver");
pro.setProperty("url", "jdbc:mysql///user");
pro.setProperty("user", "root");
pro.setProperty("password", "451535");
//1.不指定編碼 默認為:UTF-8
//storeToXML(OutputStream os, String comment)
//因為XML不是文本文件,所以只能用字節流,為不能用字符流
pro.storeToXML(new FileOutputStream("d:/others/jdbc.xml"), "數據庫配置文件");
//1.不指定編碼
//storeToXML(OutputStream os, String comment)
//因為XML不是文本文件,所以只能用字節流,為不能用字符流
pro.storeToXML(new FileOutputStream("d:/others/jdbc2.xml"), "數據庫配置文件", "GBK");
}
123456789101112131415161718
運行后效果:
*4.以properties和XML配置文件格式寫入到應用程序的某個文件夾(本例寫入應用程序的classPath類路徑下):*
public void storeToClassPsth() throws FileNotFoundException, IOException{
Properties pro=new Properties();
pro.setProperty("driver", "com.mysql.jdbc.Driver");
pro.setProperty("url", "jdbc:mysql///user");
pro.setProperty("user", "root");
pro.setProperty("password", "451535");
pro.store(new FileOutputStream("src/jdbc.properties"), "數據庫配置文件");
pro.storeToXML(new FileOutputStream("src/jdbc.xml") , "數據庫配置文件");
}
12345678910
運行后效果:
5.加載和讀取配置文件(以properties文件為例)
public void loadAndReadFile() throws FileNotFoundException, IOException{
Properties pro=new Properties();
//通過字節輸入流
//load(InputStream inStream)
pro.load(new FileInputStream("src/sql.properties"));
//通過類加載器 獲取當前類路徑
//類路徑是指 / bin路徑
pro.load(this.getClass().getResourceAsStream("/sql.properties"));
pro.load(this.getClass().getClassLoader().getResourceAsStream("sql.properties"));
//也可以使用當前上下文的類加載器,不用“/”
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("sql.properties"));
//通過字符輸入流
//load(Reader reader)
pro.load(new FileReader("src/jdbc.properties"));
System.out.println(pro.get("driver"));
//以上幾種加載配置文件的方法都可以使用,此處都列舉出來。
}
12345678910111213141516171819
運行結果:
com.mysql.jdbc.Driver
6.附上通過讀取配置文件JDBC連接數據庫的代碼干貨:
public Connection getConnection() throws Exception{
Properties info=new Properties();
info.load(this.getClass().getClassLoader().getResourceAsStream("jdbc.properties"));
String driver=info.getProperty("driver");
String jdbcUrl=info.getProperty("jdbcUrl");
String user=info.getProperty("user");
String password=info .getProperty("password");
Class.forName(driver);
Connection connection=DriverManager.getConnection(jdbcUrl,user,password);
return connection;
}
123456789101112
Java讀取Properties文件:
Java讀取Properties文件的方法有很多,詳見: Java讀取Properties文件的六種方法
但是最常用的還是通過java.lang.Class類的getResourceAsStream(String name)方法來實現
,如下可以這樣調用:
InputStream in = getClass().getResourceAsStream("資源Name");作為我們寫程序的,用
此一種足夠。
或者下面這種也常用:
InputStream in = new BufferedInputStream(new FileInputStream(filepath));
三、實例:
根據key讀取value
讀取properties的全部信息
寫入新的properties信息
//關於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
總結:通過讀取配置文件的形式可以實現代碼的深層次解耦,在java編程中,配置文件的重要性更是不言而喻。java編程有一條不成文的規定就是:“約定大於配置,配置大於代碼”意思就是能用約定的就不去配置,能用配置文件搞定的就不去寫代碼,真正牛逼的攻城獅(工程師)不是寫代碼,而是寫配置。java的一些開源框架,如:Struts、Struts2、Hibernate、Spring、MyBatis等都大量的使用配置文件,我們在學習和工作中,都應該將“約定大於配置,配置大於代碼”的思想運用到項目中,實現代碼的解耦,體現出你比別人的高明之處,才能比別人優秀。