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.Driverjdbc.url=jdbc:mysql://localhost:3306/test?useSSL=falsejdbc.username=rootjdbc.password=123456# 连接池参数jdbc.maxActive=20jdbc.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
,核心功能是读取和写入键值对配置。
2.1 Properties类的核心方法
load(InputStream in)
props.load(new FileInputStream(\"db.properties\"))
store(OutputStream out, String comments)
props.store(new FileOutputStream(\"out.properties\"), \"注释\")
getProperty(String key)
String driver = props.getProperty(\"jdbc.driver\")
getProperty(String key, String defaultValue)
String port = props.getProperty(\"jdbc.port\", \"3306\")
setProperty(String key, String value)
props.setProperty(\"jdbc.timeout\", \"30\")
stringPropertyNames()
Set 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\"); // 不存在则返回3306 System.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 2024app.author=JavaDeveloperapp.name=MyApplicationapp.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 = \"数据库配置\"; // 转为Unicode String 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通过加载
properties
文件,实现配置注入:
1. 配置文件(db.properties)
jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/test
2. Spring配置文件(spring.xml)
<context:property-placeholder location=\"classpath:db.properties\"/><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通过标签加载配置,用于动态替换SQL中的参数:
1. 配置文件(mybatis.properties)
db.username=rootdb.password=123456
2. MyBatis配置文件(mybatis-config.xml)
<configuration> <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
文件仍是简单配置的首选。
若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ