Java-Properties类和properties文件详解
Java-Properties类和properties文件详解
- 一、properties配置文件基础
- 1.1 什么是properties文件?
- 示例:db.properties(数据库配置)
- 1.2 properties文件的语法规则
- 1.3 properties文件的优势
- 二、Properties类详解
- 2.1 Properties类的核心方法
- 2.2 Properties类的使用流程
- 三、Properties类操作properties文件
- 3.1 读取properties文件
- 3.1.1 读取类路径下的properties文件
- 3.1.2 读取绝对路径的properties文件
- 3.2 写入properties文件
- 3.3 处理包含中文的properties文件
- 方式1:手动转义中文(不推荐)
- 方式2:使用UTF-8编码读写(推荐)
- 四、properties文件在框架中的应用
- 4.1 Spring框架中的properties文件
- 1. 配置文件(db.properties)
- 2. Spring配置文件(spring.xml)
- 4.2 MyBatis中的properties文件
- 1. 配置文件(mybatis.properties)
- 2. MyBatis配置文件(mybatis-config.xml)
- 五、常见问题与避坑指南
- 5.1 读取文件时出现NullPointerException
- 5.2 中文乱码问题
- 5.3 配置覆盖问题
- 总结
Java开发中配置文件是存储程序参数的常用方式,而properties
文件因其简洁的键值对格式,成为最常用的配置文件类型之一,与之配套的java.util.Properties
类,则是操作properties
文件的核心工具。
一、properties配置文件基础
1.1 什么是properties文件?
properties
文件是一种以.properties
为后缀的文本文件,采用键值对(key=value) 格式存储数据,主要用于存储配置信息(如数据库连接参数、系统参数等)。
示例:db.properties(数据库配置)
# 数据库连接配置(#为注释)
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false
jdbc.username=root
jdbc.password=123456
# 连接池参数
jdbc.maxActive=20
jdbc.minIdle=5
1.2 properties文件的语法规则
- 键值对格式:
key=value
(等号前后可空格,如key = value
); - 注释:以
#
或!
开头的行(如# 这是注释
、! 这也是注释
); - 换行规则:一行一个键值对,若值过长需换行,可在末尾加
\
(如key=value1\
+换行+value2
); - 编码:Java默认以ISO-8859-1编码读取,若包含中文需特殊处理(后续讲解);
- 大小写敏感:
key
和value
区分大小写(如Name
和name
是不同的key)。
1.3 properties文件的优势
- 简洁直观:键值对格式易于读写和维护;
- 跨平台:文本文件,可在不同系统中使用;
- 与Java无缝集成:
Properties
类原生支持,无需额外依赖; - 动态配置:无需修改代码,通过修改配置文件即可调整程序行为。
二、Properties类详解
java.util.Properties
是Java提供的操作properties
文件的工具类,继承自Hashtable<Object, Object>
,核心功能是读取和写入键值对配置。
2.1 Properties类的核心方法
方法名 | 作用 | 示例 |
---|---|---|
load(InputStream in) | 从输入流读取properties文件内容 | props.load(new FileInputStream("db.properties")) |
store(OutputStream out, String comments) | 将键值对写入输出流(生成properties文件) | props.store(new FileOutputStream("out.properties"), "注释") |
getProperty(String key) | 根据key获取value(返回String) | String driver = props.getProperty("jdbc.driver") |
getProperty(String key, String defaultValue) | 获取value,若key不存在则返回默认值 | String port = props.getProperty("jdbc.port", "3306") |
setProperty(String key, String value) | 设置键值对(添加或修改) | props.setProperty("jdbc.timeout", "30") |
stringPropertyNames() | 获取所有key的集合(返回Set) | Set<String> keys = props.stringPropertyNames() |
2.2 Properties类的使用流程
使用Properties
类操作配置文件的通用流程:
- 创建
Properties
对象; - 通过
load()
方法读取properties
文件; - 通过
getProperty()
获取配置值; - (可选)通过
setProperty()
修改配置; - (可选)通过
store()
写入新的properties
文件。
三、Properties类操作properties文件
3.1 读取properties文件
3.1.1 读取类路径下的properties文件
在Maven项目中,properties
文件通常放在src/main/resources
目录下(编译后位于类路径),读取方式:
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. 创建Properties对象Properties props = new Properties();try (// 2. 获取类路径下的文件输入流(自动关闭流)InputStream in = PropertiesReadDemo.class.getClassLoader().getResourceAsStream("db.properties")) {if (in == null) {throw new RuntimeException("未找到db.properties文件");}// 3. 加载文件内容props.load(in);// 4. 读取配置(方式1:指定key)String driver = props.getProperty("jdbc.driver");String url = props.getProperty("jdbc.url");System.out.println("数据库驱动:" + 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:带默认值)String port = props.getProperty("jdbc.port", "3306"); // 不存在则返回3306System.out.println("\n数据库端口:" + port);} catch (IOException e) {e.printStackTrace();}}
}
关键说明:
getClassLoader().getResourceAsStream("db.properties")
:从类路径读取文件,无需关心具体路径;- 使用try-with-resources语法自动关闭输入流,避免资源泄露;
getProperty
支持默认值,适合处理可选配置。
3.1.2 读取绝对路径的properties文件
若文件不在类路径下(如D:/config/db.properties
),需通过绝对路径读取:
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();// 绝对路径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 写入properties文件
通过store()
方法可将Properties
对象中的键值对写入文件,常用于生成配置或保存修改。
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. 创建Properties对象并添加配置Properties props = new Properties();props.setProperty("app.name", "MyApplication");props.setProperty("app.version", "1.0.0");props.setProperty("app.author", "JavaDeveloper");// 2. 写入文件String filePath = "src/main/resources/app.properties";try (OutputStream out = new FileOutputStream(filePath)) {// store(输出流, 注释):注释会被添加到文件开头props.store(out, "Application Configuration");System.out.println("配置文件写入成功:" + filePath);} catch (IOException e) {e.printStackTrace();}}
}
生成的app.properties内容:
#Application Configuration
#Mon Jul 29 15:30:00 CST 2024
app.author=JavaDeveloper
app.name=MyApplication
app.version=1.0.0
注意:store()
会自动添加时间戳注释,且键值对按ASCII排序输出。
3.3 处理包含中文的properties文件
properties
文件默认以ISO-8859-1编码存储,直接写入中文会导致乱码。解决方式有两种:
方式1:手动转义中文(不推荐)
将中文转为Unicode编码(如中文
→\u4E2D\u6587
),可通过Java工具类实现:
public class ChineseEscapeDemo {public static void main(String[] args) {String chinese = "数据库配置";// 转为UnicodeString unicode = new String(escapeChinese(chinese).getBytes());System.out.println(unicode); // 输出:\u6570\u636E\u5E93\u914D\u7F6E}// 中文转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();}
}
缺点:可读性差,维护困难,仅适合少量中文场景。
方式2:使用UTF-8编码读写(推荐)
通过InputStreamReader
和OutputStreamWriter
指定UTF-8编码,直接读写中文。
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Properties;public class PropertiesUtf8Demo {public static void main(String[] args) {// 1. 写入UTF-8编码的properties文件(含中文)Properties props = new Properties();props.setProperty("app.name", "我的应用");props.setProperty("app.desc", "这是一个测试应用");try (OutputStream out = new FileOutputStream("src/main/resources/app_utf8.properties");// 指定UTF-8编码写入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("应用名称:" + readProps.getProperty("app.name")); // 输出:我的应用System.out.println("应用描述:" + readProps.getProperty("app.desc")); // 输出:这是一个测试应用} catch (IOException e) {e.printStackTrace();}}
}
关键:读写时均通过InputStreamReader
和OutputStreamWriter
指定UTF_8
编码,确保中文正常显示。
四、properties文件在框架中的应用
properties
文件是Java框架的标配配置方式,以Spring和MyBatis为例:
4.1 Spring框架中的properties文件
Spring通过<context:property-placeholder>
加载properties
文件,实现配置注入:
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通过<properties>
标签加载配置,用于动态替换SQL中的参数:
1. 配置文件(mybatis.properties)
db.username=root
db.password=123456
2. MyBatis配置文件(mybatis-config.xml)
<configuration><!-- 加载properties文件 --><properties resource="mybatis.properties"/><!-- 在数据源中引用 --><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>
五、常见问题与避坑指南
5.1 读取文件时出现NullPointerException
错误:InputStream in = ...
返回null
,导致props.load(in)
报错。
原因:
- 文件路径错误(如类路径下不存在该文件);
- 使用
Class.getResourceAsStream()
时,路径前缺少/
(相对路径问题)。
解决方案:
- 确认文件位置:Maven项目中,
src/main/resources
下的文件编译后位于类路径根目录; - 正确获取流:
// 类路径根目录下的文件 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 中文乱码问题
错误:读取properties文件中的中文显示为???
或乱码。
原因:
- 未指定UTF-8编码读写(默认ISO-8859-1);
- 文件实际编码与读写编码不一致(如文件是GBK,却用UTF-8读取)。
解决方案:
- 统一使用UTF-8编码读写(通过
InputStreamReader
和OutputStreamWriter
); - 检查文件实际编码(右键文件→查看/修改编码格式)。
5.3 配置覆盖问题
问题:setProperty
后未调用store
,修改未保存到文件。
原因:Properties
是内存中的对象,setProperty
仅修改内存数据,需调用store
才能写入文件。
解决方案:
- 修改后必须调用
store
方法,否则修改不会持久化:
props.setProperty("jdbc.url", "新URL");
// 必须调用store才能保存到文件
props.store(new FileOutputStream("db.properties"), "更新URL");
总结
properties
文件和Properties
类是Java中轻量级配置解决方案:
- 简单易用:键值对格式和
Properties
类的API都非常直观,学习成本低; - 灵活通用:适用于各种场景(数据库配置、系统参数、框架配置等);
- 无缝集成:与Java及主流框架(Spring、MyBatis)完美兼容;
- 便于维护:配置与代码分离,修改配置无需重新编译程序。
在实际开发中,需注意编码问题(尤其是中文)和路径问题(确保文件能被正确读取),对于复杂配置(如嵌套结构),可考虑JSON或XML,但properties
文件仍是简单配置的首选。
若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ