properties.load()抛ioexception主因是路径错误和编码不匹配:默认iso-8859-1解码utf-8文件会乱码或报错;应优先用load(reader)指定utf-8编码,classpath资源须用getresourceasstream()获取流。

Properties.load() 读取文件时抛出 IOException:路径和编码是主因
Java 的 Properties 默认用 ISO-8859-1 解码,而你编辑的 .properties 文件大概率是 UTF-8(尤其含中文)。直接 load(InputStream) 会乱码甚至报 java.io.IOException: Invalid Unicode sequence。
常见错误现象:key=value 看起来正常,但 getProperty("中文键") 返回 null;或加载时直接抛异常。
- 优先用
load(Reader)替代load(InputStream),显式指定编码:props.load(new InputStreamReader(inputStream, "UTF-8")) - 资源在 classpath 下(如
src/main/resources/config.properties),别用new FileInputStream("config.properties")—— 路径错、打包后找不到。改用:getClass().getResourceAsStream("/config.properties") - 如果必须用
load(InputStream)(比如兼容旧逻辑),确保文件里中文用 Unicode 转义(\u4f60\u597d),但不推荐——难维护
setProperty() 后如何保存到文件:注意流关闭和编码一致性
Properties.setProperty() 只改内存对象,不自动写回磁盘。调用 store() 才真正落盘,但默认又切回 ISO-8859-1,中文会变问号。
使用场景:运行时动态更新配置并持久化(如管理后台修改开关)。
立即学习“Java免费学习笔记(深入)”;
- 用
store(Writer, String),而非store(OutputStream, String):props.store(new FileWriter("config.properties", false), "updated by Java") - 如果文件已存在且含中文,
FileWriter默认用系统编码(Windows 是 GBK),可能污染内容。稳妥做法:new OutputStreamWriter(new FileOutputStream("config.properties"), "UTF-8") -
store()会覆盖整个文件,不会只改某一行。别指望它做“增量保存”
getProperty() 返回 null 的三种真实原因
不是所有 null 都是键不存在。容易误判,导致空指针或逻辑跳过。
- 键存在但值为空字符串(
key=):getProperty("key")返回"",不是null - 键存在但值为
key=后跟空格(key=):仍返回" ",不是null - 真正返回
null的只有两种情况:键未定义;或键定义了但被注释掉(#key=value或!key=value)——注释行不参与加载
所以判断是否存在,别只靠 == null,要结合 containsKey() 或检查原始行内容(需自己解析)。
Properties 不是 Map 的安全替代品:线程和类型隐患
虽然 Properties 继承自 Hashtable,但它的设计目标只是配置读写,不是通用容器。
- 多线程写入(如多个地方调用
setProperty()+store())会竞争同一文件,没内置锁。得自己加同步或用临时文件+原子重命名 -
getProperty()返回String,但get(key)(继承自Map)返回Object,混用易引发ClassCastException - 加载时遇到语法错误(如等号前有空格、反斜杠未转义),
load()会静默跳过整行,不报错也不警告——配置丢了都不知道
复杂配置建议换 Apache Commons Configuration 或 Typesafe Config,Properties 适合简单、静态、单线程场景。










