Java中Properties類(lèi)和properties文件示例詳解
前言
Java開(kāi)發(fā)中配置文件是存儲(chǔ)程序參數(shù)的常用方式,而properties文件因其簡(jiǎn)潔的鍵值對(duì)格式,成為最常用的配置文件類(lèi)型之一,與之配套的java.util.Properties類(lèi),則是操作properties文件的核心工具。
一、properties配置文件基礎(chǔ)
1.1 什么是properties文件?
properties文件是一種以.properties為后綴的文本文件,采用鍵值對(duì)(key=value) 格式存儲(chǔ)數(shù)據(jù),主要用于存儲(chǔ)配置信息(如數(shù)據(jù)庫(kù)連接參數(shù)、系統(tǒng)參數(shù)等)。
示例:db.properties(數(shù)據(jù)庫(kù)配置)
# 數(shù)據(jù)庫(kù)連接配置(#為注釋?zhuān)? jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false jdbc.username=root jdbc.password=123456 # 連接池參數(shù) jdbc.maxActive=20 jdbc.minIdle=5
1.2 properties文件的語(yǔ)法規(guī)則
- 鍵值對(duì)格式:
key=value(等號(hào)前后可空格,如key = value); - 注釋:以
#或!開(kāi)頭的行(如# 這是注釋、! 這也是注釋); - 換行規(guī)則:一行一個(gè)鍵值對(duì),若值過(guò)長(zhǎng)需換行,可在末尾加
\(如key=value1\+換行+value2); - 編碼:Java默認(rèn)以ISO-8859-1編碼讀取,若包含中文需特殊處理(后續(xù)講解);
- 大小寫(xiě)敏感:
key和value區(qū)分大小寫(xiě)(如Name和name是不同的key)。
1.3 properties文件的優(yōu)勢(shì)
- 簡(jiǎn)潔直觀:鍵值對(duì)格式易于讀寫(xiě)和維護(hù);
- 跨平臺(tái):文本文件,可在不同系統(tǒng)中使用;
- 與Java無(wú)縫集成:
Properties類(lèi)原生支持,無(wú)需額外依賴(lài); - 動(dòng)態(tài)配置:無(wú)需修改代碼,通過(guò)修改配置文件即可調(diào)整程序行為。
二、Properties類(lèi)詳解
java.util.Properties是Java提供的操作properties文件的工具類(lèi),繼承自Hashtable<Object, Object>,核心功能是讀取和寫(xiě)入鍵值對(duì)配置。
2.1 Properties類(lèi)的核心方法
| 方法名 | 作用 | 示例 |
|---|---|---|
load(InputStream in) | 從輸入流讀取properties文件內(nèi)容 | props.load(new FileInputStream("db.properties")) |
store(OutputStream out, String comments) | 將鍵值對(duì)寫(xiě)入輸出流(生成properties文件) | props.store(new FileOutputStream("out.properties"), "注釋") |
getProperty(String key) | 根據(jù)key獲取value(返回String) | String driver = props.getProperty("jdbc.driver") |
getProperty(String key, String defaultValue) | 獲取value,若key不存在則返回默認(rèn)值 | String port = props.getProperty("jdbc.port", "3306") |
setProperty(String key, String value) | 設(shè)置鍵值對(duì)(添加或修改) | props.setProperty("jdbc.timeout", "30") |
stringPropertyNames() | 獲取所有key的集合(返回Set) | Set<String> keys = props.stringPropertyNames() |
2.2 Properties類(lèi)的使用流程
使用Properties類(lèi)操作配置文件的通用流程:
- 創(chuàng)建
Properties對(duì)象; - 通過(guò)
load()方法讀取properties文件; - 通過(guò)
getProperty()獲取配置值; - (可選)通過(guò)
setProperty()修改配置; - (可選)通過(guò)
store()寫(xiě)入新的properties文件。
三、Properties類(lèi)操作properties文件
3.1 讀取properties文件
3.1.1 讀取類(lèi)路徑下的properties文件
在Maven項(xiàng)目中,properties文件通常放在src/main/resources目錄下(編譯后位于類(lèi)路徑),讀取方式:
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Set;
public class PropertiesReadDemo {
public static void main(String[] args) {
// 1. 創(chuàng)建Properties對(duì)象
Properties props = new Properties();
try (
// 2. 獲取類(lèi)路徑下的文件輸入流(自動(dòng)關(guān)閉流)
InputStream in = PropertiesReadDemo.class.getClassLoader().getResourceAsStream("db.properties")
) {
if (in == null) {
throw new RuntimeException("未找到db.properties文件");
}
// 3. 加載文件內(nèi)容
props.load(in);
// 4. 讀取配置(方式1:指定key)
String driver = props.getProperty("jdbc.driver");
String url = props.getProperty("jdbc.url");
System.out.println("數(shù)據(jù)庫(kù)驅(qū)動(dòng):" + driver);
System.out.println("連接URL:" + url);
// 4. 讀取配置(方式2:遍歷所有key)
Set<String> keys = props.stringPropertyNames();
System.out.println("\n所有配置:");
for (String key : keys) {
String value = props.getProperty(key);
System.out.println(key + " = " + value);
}
// 4. 讀取配置(方式3:帶默認(rèn)值)
String port = props.getProperty("jdbc.port", "3306"); // 不存在則返回3306
System.out.println("\n數(shù)據(jù)庫(kù)端口:" + port);
} catch (IOException e) {
e.printStackTrace();
}
}
}
關(guān)鍵說(shuō)明:
getClassLoader().getResourceAsStream("db.properties"):從類(lèi)路徑讀取文件,無(wú)需關(guān)心具體路徑;- 使用try-with-resources語(yǔ)法自動(dòng)關(guān)閉輸入流,避免資源泄露;
getProperty支持默認(rèn)值,適合處理可選配置。
3.1.2 讀取絕對(duì)路徑的properties文件
若文件不在類(lèi)路徑下(如D:/config/db.properties),需通過(guò)絕對(duì)路徑讀?。?/p>
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesAbsolutePathDemo {
public static void main(String[] args) {
Properties props = new Properties();
// 絕對(duì)路徑
String filePath = "D:/config/db.properties";
try (InputStream in = new FileInputStream(filePath)) {
props.load(in);
System.out.println("用戶名:" + props.getProperty("jdbc.username"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2 寫(xiě)入properties文件
通過(guò)store()方法可將Properties對(duì)象中的鍵值對(duì)寫(xiě)入文件,常用于生成配置或保存修改。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class PropertiesWriteDemo {
public static void main(String[] args) {
// 1. 創(chuàng)建Properties對(duì)象并添加配置
Properties props = new Properties();
props.setProperty("app.name", "MyApplication");
props.setProperty("app.version", "1.0.0");
props.setProperty("app.author", "JavaDeveloper");
// 2. 寫(xiě)入文件
String filePath = "src/main/resources/app.properties";
try (OutputStream out = new FileOutputStream(filePath)) {
// store(輸出流, 注釋):注釋會(huì)被添加到文件開(kāi)頭
props.store(out, "Application Configuration");
System.out.println("配置文件寫(xiě)入成功:" + filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
生成的app.properties內(nèi)容:
#Application Configuration #Mon Jul 29 15:30:00 CST 2024 app.author=JavaDeveloper app.name=MyApplication app.version=1.0.0
注意:store()會(huì)自動(dòng)添加時(shí)間戳注釋?zhuān)益I值對(duì)按ASCII排序輸出。
3.3 處理包含中文的properties文件
properties文件默認(rèn)以ISO-8859-1編碼存儲(chǔ),直接寫(xiě)入中文會(huì)導(dǎo)致亂碼。解決方式有兩種:
方式1:手動(dòng)轉(zhuǎn)義中文(不推薦)
將中文轉(zhuǎn)為Unicode編碼(如中文→\u4E2D\u6587),可通過(guò)Java工具類(lèi)實(shí)現(xiàn):
public class ChineseEscapeDemo {
public static void main(String[] args) {
String chinese = "數(shù)據(jù)庫(kù)配置";
// 轉(zhuǎn)為Unicode
String unicode = new String(escapeChinese(chinese).getBytes());
System.out.println(unicode); // 輸出:\u6570\u636E\u5E93\u914D\u7F6E
}
// 中文轉(zhuǎn)Unicode工具方法
private static String escapeChinese(String str) {
StringBuilder sb = new StringBuilder();
for (char c : str.toCharArray()) {
if (c > 127) {
sb.append("\\u").append(Integer.toHexString(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
}
缺點(diǎn):可讀性差,維護(hù)困難,僅適合少量中文場(chǎng)景。
方式2:使用UTF-8編碼讀寫(xiě)(推薦)
通過(guò)InputStreamReader和OutputStreamWriter指定UTF-8編碼,直接讀寫(xiě)中文。
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class PropertiesUtf8Demo {
public static void main(String[] args) {
// 1. 寫(xiě)入U(xiǎn)TF-8編碼的properties文件(含中文)
Properties props = new Properties();
props.setProperty("app.name", "我的應(yīng)用");
props.setProperty("app.desc", "這是一個(gè)測(cè)試應(yīng)用");
try (
OutputStream out = new FileOutputStream("src/main/resources/app_utf8.properties");
// 指定UTF-8編碼寫(xiě)入
Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)
) {
props.store(writer, "UTF-8編碼的配置文件(含中文)");
} catch (IOException e) {
e.printStackTrace();
}
// 2. 讀取UTF-8編碼的properties文件
try (
InputStream in = new FileInputStream("src/main/resources/app_utf8.properties");
// 指定UTF-8編碼讀取
Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8)
) {
Properties readProps = new Properties();
readProps.load(reader);
System.out.println("應(yīng)用名稱(chēng):" + readProps.getProperty("app.name")); // 輸出:我的應(yīng)用
System.out.println("應(yīng)用描述:" + readProps.getProperty("app.desc")); // 輸出:這是一個(gè)測(cè)試應(yīng)用
} catch (IOException e) {
e.printStackTrace();
}
}
}
關(guān)鍵:讀寫(xiě)時(shí)均通過(guò)InputStreamReader和OutputStreamWriter指定UTF_8編碼,確保中文正常顯示。
四、properties文件在框架中的應(yīng)用
properties文件是Java框架的標(biāo)配配置方式,以Spring和MyBatis為例:
4.1 Spring框架中的properties文件
Spring通過(guò)<context:property-placeholder>加載properties文件,實(shí)現(xiàn)配置注入:
1. 配置文件(db.properties)
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test
2. Spring配置文件(spring.xml)
<!-- 加載properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 注入配置到Bean -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
</bean>
4.2 MyBatis中的properties文件
MyBatis通過(guò)<properties>標(biāo)簽加載配置,用于動(dòng)態(tài)替換SQL中的參數(shù):
1. 配置文件(mybatis.properties)
db.username=root db.password=123456
2. MyBatis配置文件(mybatis-config.xml)
<configuration>
<!-- 加載properties文件 -->
<properties resource="mybatis.properties"/>
<!-- 在數(shù)據(jù)源中引用 -->
<environments default="development">
<environment id="development">
<dataSource type="POOLED">
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
五、常見(jiàn)問(wèn)題與避坑指南
5.1 讀取文件時(shí)出現(xiàn)NullPointerException
錯(cuò)誤:InputStream in = ...返回null,導(dǎo)致props.load(in)報(bào)錯(cuò)。
原因:
- 文件路徑錯(cuò)誤(如類(lèi)路徑下不存在該文件);
- 使用
Class.getResourceAsStream()時(shí),路徑前缺少/(相對(duì)路徑問(wèn)題)。
解決方案:
- 確認(rèn)文件位置:Maven項(xiàng)目中,
src/main/resources下的文件編譯后位于類(lèi)路徑根目錄; - 正確獲取流:
// 類(lèi)路徑根目錄下的文件 InputStream in = PropertiesDemo.class.getClassLoader().getResourceAsStream("db.properties"); // 若文件在包下(如com/example/config/db.properties) InputStream in = PropertiesDemo.class.getResourceAsStream("/com/example/config/db.properties");
5.2 中文亂碼問(wèn)題
錯(cuò)誤:讀取properties文件中的中文顯示為???或亂碼。
原因:
- 未指定UTF-8編碼讀寫(xiě)(默認(rèn)ISO-8859-1);
- 文件實(shí)際編碼與讀寫(xiě)編碼不一致(如文件是GBK,卻用UTF-8讀?。?。
解決方案:
- 統(tǒng)一使用UTF-8編碼讀寫(xiě)(通過(guò)
InputStreamReader和OutputStreamWriter); - 檢查文件實(shí)際編碼(右鍵文件→查看/修改編碼格式)。
5.3 配置覆蓋問(wèn)題
問(wèn)題:setProperty后未調(diào)用store,修改未保存到文件。
原因:Properties是內(nèi)存中的對(duì)象,setProperty僅修改內(nèi)存數(shù)據(jù),需調(diào)用store才能寫(xiě)入文件。
解決方案:
- 修改后必須調(diào)用
store方法,否則修改不會(huì)持久化:
props.setProperty("jdbc.url", "新URL");
// 必須調(diào)用store才能保存到文件
props.store(new FileOutputStream("db.properties"), "更新URL");
總結(jié)
properties文件和Properties類(lèi)是Java中輕量級(jí)配置解決方案:
- 簡(jiǎn)單易用:鍵值對(duì)格式和
Properties類(lèi)的API都非常直觀,學(xué)習(xí)成本低; - 靈活通用:適用于各種場(chǎng)景(數(shù)據(jù)庫(kù)配置、系統(tǒng)參數(shù)、框架配置等);
- 無(wú)縫集成:與Java及主流框架(Spring、MyBatis)完美兼容;
- 便于維護(hù):配置與代碼分離,修改配置無(wú)需重新編譯程序。
在實(shí)際開(kāi)發(fā)中,需注意編碼問(wèn)題(尤其是中文)和路徑問(wèn)題(確保文件能被正確讀?。瑢?duì)于復(fù)雜配置(如嵌套結(jié)構(gòu)),可考慮JSON或XML,但properties文件仍是簡(jiǎn)單配置的首選。
到此這篇關(guān)于Java中Properties類(lèi)和properties文件的文章就介紹到這了,更多相關(guān)Java Properties類(lèi)和properties文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Elasticsearch 基礎(chǔ)介紹及索引原理分析
這篇文章主要介紹了Elasticsearch 基礎(chǔ)介紹及索引原理分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
java?工作流引擎設(shè)計(jì)實(shí)現(xiàn)解析流程定義文件
這篇文章主要為大家介紹了java?工作流引擎設(shè)計(jì)與實(shí)現(xiàn)及流程定義文件解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
IDEA JAVA項(xiàng)目熱加載的實(shí)現(xiàn)步驟
熱加載可以使代碼修改后無(wú)須重啟服務(wù)器,就可以加載更改的代碼,本文主要介紹了IDEA JAVA項(xiàng)目熱加載的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2023-06-06
idea上提交項(xiàng)目到gitee 最后出現(xiàn) Push rejected的問(wèn)題處理方法
這篇文章主要介紹了idea上面提交項(xiàng)目到gitee 最后出現(xiàn) Push rejected的問(wèn)題處理方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Spring中的之啟動(dòng)過(guò)程obtainFreshBeanFactory詳解
這篇文章主要介紹了Spring中的之啟動(dòng)過(guò)程obtainFreshBeanFactory詳解,在refresh時(shí),prepareRefresh后,馬上就調(diào)用了obtainFreshBeanFactory創(chuàng)建beanFactory以及掃描bean信息(beanDefinition),并通過(guò)BeanDefinitionRegistry注冊(cè)到容器中,需要的朋友可以參考下2024-02-02
IDEA類(lèi)和方法注釋模板設(shè)置(非常詳細(xì))
這篇文章主要介紹了IDEA類(lèi)和方法注釋模板設(shè)置(非常詳細(xì)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Java調(diào)用SSE流式接口并流式返回給前端實(shí)現(xiàn)打字輸出效果
在Web開(kāi)發(fā)中,有時(shí)我們需要將文件以流的形式返回給前端,下面這篇文章主要給大家介紹了關(guān)于Java調(diào)用SSE流式接口并流式返回給前端實(shí)現(xiàn)打字輸出效果的相關(guān)資料,需要的朋友可以參考下2024-08-08
深入Ajax代理的Java Servlet的實(shí)現(xiàn)詳解
本篇文章是對(duì)Ajax代理的Java Servlet的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Java?JVM虛擬機(jī)調(diào)優(yōu)詳解
JVM是JavaVirtualMachine(Java虛擬機(jī))的縮寫(xiě),JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的,本文主要介紹了jvm調(diào)優(yōu),感興趣的小伙伴們可以參考一下<BR>2022-07-07

