> 技术文档 > Java-Properties类和properties文件详解

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文件的语法规则

  1. 键值对格式key=value(等号前后可空格,如key = value);
  2. 注释:以#!开头的行(如# 这是注释! 这也是注释);
  3. 换行规则:一行一个键值对,若值过长需换行,可在末尾加\\(如key=value1\\+换行+value2);
  4. 编码:Java默认以ISO-8859-1编码读取,若包含中文需特殊处理(后续讲解);
  5. 大小写敏感keyvalue区分大小写(如Namename是不同的key)。

1.3 properties文件的优势

  • 简洁直观:键值对格式易于读写和维护;
  • 跨平台:文本文件,可在不同系统中使用;
  • 与Java无缝集成Properties类原生支持,无需额外依赖;
  • 动态配置:无需修改代码,通过修改配置文件即可调整程序行为。

二、Properties类详解

java.util.Properties是Java提供的操作properties文件的工具类,继承自Hashtable,核心功能是读取和写入键值对配置

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 keys = props.stringPropertyNames()

2.2 Properties类的使用流程

使用Properties类操作配置文件的通用流程:

  1. 创建Properties对象;
  2. 通过load()方法读取properties文件;
  3. 通过getProperty()获取配置值;
  4. (可选)通过setProperty()修改配置;
  5. (可选)通过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编码读写(推荐)

通过InputStreamReaderOutputStreamWriter指定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(); } }}

关键:读写时均通过InputStreamReaderOutputStreamWriter指定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编码读写(通过InputStreamReaderOutputStreamWriter);
  • 检查文件实际编码(右键文件→查看/修改编码格式)。

5.3 配置覆盖问题

问题setProperty后未调用store,修改未保存到文件。

原因Properties是内存中的对象,setProperty仅修改内存数据,需调用store才能写入文件。

解决方案

  • 修改后必须调用store方法,否则修改不会持久化:
props.setProperty(\"jdbc.url\", \"新URL\");// 必须调用store才能保存到文件props.store(new FileOutputStream(\"db.properties\"), \"更新URL\");

总结

properties文件和Properties类是Java中轻量级配置解决方案:

  1. 简单易用:键值对格式和Properties类的API都非常直观,学习成本低;
  2. 灵活通用:适用于各种场景(数据库配置、系统参数、框架配置等);
  3. 无缝集成:与Java及主流框架(Spring、MyBatis)完美兼容;
  4. 便于维护:配置与代码分离,修改配置无需重新编译程序。

在实际开发中,需注意编码问题(尤其是中文)和路径问题(确保文件能被正确读取),对于复杂配置(如嵌套结构),可考虑JSON或XML,但properties文件仍是简单配置的首选。

若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ