在Java里如何使用Properties类管理配置文件_Java配置文件操作说明

Properties.load()默认ISO-8859-1导致中文乱码,应使用InputStreamReader指定UTF-8编码加载;setProperty()不自动持久化,需显式调用store()或storeToXML();classpath路径需注意前导/;Properties与System.getProperty()无关,需手动合并;所有值均为字符串,类型转换须校验。

Properties.load() 读取配置文件时中文乱码怎么办

Java 的 Properties 默认用 ISO-8859-1 解析文件,遇到含中文的 .properties 文件会直接显示为 \u4f60\u597d 这类 Unicode 转义,而不是正常文字。

  • 最稳妥的做法是改用 InputStreamReader 指定 UTF-8 编码再加载:
    try (InputStream is = getClass().getResourceAsStream("/config.properties");
         InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
        Properties props = new Properties();
        props.load(reader);
    }
  • 不要依赖 IDE 自动保存为 UTF-8 就万事大吉——Properties.store() 写入时仍会强制转义中文,除非你手动用 storeToXML() 或自定义输出逻辑
  • 如果必须用

    load(FileInputStream),且文件已存为 UTF-8,务必加 new InputStreamReader(in, "UTF-8"),否则乱码不可避免

Properties.setProperty() 后如何持久化到磁盘

setProperty() 只修改内存中的键值对,不自动写回文件。要保存,必须显式调用 store()storeToXML()

  • store(OutputStream, String comments) 输出为传统 key=value 格式,但所有非 ISO-8859-1 字符会被转义(如中文变 \u6211\u4eec
  • 若需保留原始中文可读性,改用 storeToXML()
    props.storeToXML(new FileOutputStream("config.xml"), "auto-generated");
    // 生成的是 XML 格式,中文原样保留
  • 注意:store() 会覆盖整个文件,无法只更新单个 key;如需增量修改,得先 load(),再 setProperty(),最后 store()

从 classpath 加载 properties 文件的路径陷阱

getClass().getResourceAsStream("/config.properties") 时,路径开头的 / 表示从 classpath 根开始找;不加则相对当前类所在包路径查找。

  • 常见错误:把 config.properties 放在 src/main/resources 下,却写成 getResourceAsStream("config.properties")(缺 /),结果返回 null
  • Maven 项目中,resources 目录内容会被复制到 target/classes/,所以 /config.properties 实际对应的是 target/classes/config.properties
  • 运行时若提示 NullPointerException,先检查流是否为 null,再确认文件是否真在 classpath 中(解压 jar 包验证)

Properties 和 System.getProperty() 的关系与误用

Properties 是通用配置容器,而 System.getProperty() 读取的是 JVM 启动参数(-Dkey=value),两者完全独立,不能互相替代。

  • 别试图用 System.setProperty("k", "v") 来“模拟”配置文件行为——它只影响系统属性,不会被 Properties.load() 加载
  • 若想合并多种来源(JVM 参数 + 配置文件),需手动处理:
    Properties props = new Properties();
    props.load(...); // 从文件加载
    props.putAll(System.getProperties()); // 合并系统属性(注意 key 冲突)
  • System.getProperties() 返回的是不可变快照,后续 System.setProperty() 不会影响已取出的这个 Properties 对象
实际项目里最容易被忽略的是:**Properties 不支持嵌套或类型推断,所有值都是字符串,数值、布尔值都需要手动 Integer.parseInt()Boolean.parseBoolean() ——没做校验就直接强转,运行时 NumberFormatException 很常见。**