当前位置: 首页 > news >正文

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

  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<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类操作配置文件的通用流程:

  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"); // 不存在则返回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编码读写(推荐)

通过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通过<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编码读写(通过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文件仍是简单配置的首选。

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

http://www.dtcms.com/a/297883.html

相关文章:

  • 同声传译新突破!字节跳动发布 Seed LiveInterpret 2.0
  • 深入探索嵌入式仿真教学:以酒精测试仪实验为例的高效学习实践
  • C++常见面试题之一
  • win11平台上mysql 数据库迁移
  • 【C#补全计划:类和对象(七)—— 重写虚方法】
  • CMOS知识点 双阱工艺 三阱工艺
  • 大数据中心——解读60页IDC云数据中心机房运维服务解决方案【附全文阅读】
  • 【优选算法】链表
  • 2025.7.25 测试 总结
  • C/C++---I/O性能优化
  • ISAAC ROS 在Jetson Orin NX上的部署
  • 自动化UI测试工具TestComplete的AI双引擎:即时数据集 + 自愈测试
  • BGP负载均衡-9
  • C#观察者模式示例代码
  • Qt 拔网线等情况下收不到disconnected()信号
  • 数据结构之 【排序】(非递归实现快速排序)
  • 【Web安全】逻辑漏洞之URL跳转漏洞:原理、场景与防御
  • QEMU RISCV TCG 详解六 -- RISCV CPU 的使能(How a RISCV CPU Realized)
  • 算法:数组part02: 209. 长度最小的子数组 +
  • 视频孪生技术赋能仓储智慧化转型
  • Leetcode力扣解题记录--第21题(合并链表)
  • 已解决:Please check the setting of primary
  • 自定义控件
  • 逆向工程信息抽象层次详解
  • 指令改图,换背景/改文字/调光影等
  • Spring Boot2 静态资源、Rest映射、请求映射源码分析
  • SAP在未启用负库存的情况下,库存却出现了负数-补充S4 1709 BUG
  • Text Edit + ComboBox 属性(2)
  • SpringBoot(黑马)
  • Ansible自动化运维工具详解