Java中用Properties读取配置文件的正确姿势是:必须用InputStreamReader指定UTF-8编码加载,通过ClassLoader.getResourceAsStream()获取路径,注意键值空格自动截断及资源存在性校验。

Java中用Properties读取配置文件的正确姿势
直接用Properties类读取.properties文件没问题,但多数人卡在路径不对、编码乱码、键值空格处理这三处。核心不是“能不能读”,而是“读得准不准”。
关键点:
-
Properties默认使用ISO-8859-1解码,含中文必须显式指定Reader并设UTF-8 - 资源路径用
ClassLoader.getResourceAsStream(),别用FileInputStream硬写相对路径 - 键末尾的空格会被自动trim,值开头的空格也会被吃掉——这是规范行为,不是bug
Properties props = new Properties();
try (InputStream is = YourClass.class.getClassLoader().getResourceAsStream("config.properties")) {
if (is == null) {
throw new IllegalArgumentException("config.properties not found in classpath");
}
props.load(is); // 这里不支持UTF-8!
}解决中文乱码:必须绕过load(InputStream)
Properties.load(InputStream)强制按ISO-8859-1解析,哪怕文件存的是UTF-8,中文也会变问号或方块。唯一可靠方式是用Reader接口。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 用
InputStreamReader包装流,并明确传入StandardCharsets.UTF_8 - 不要依赖系统默认编码,哪怕本地跑通,上线到Linux可能崩
- 如果配置文件由非程序员编辑(如运营同事),建议在文件头加
# encoding=UTF-8注释,仅作提示,不被解析
Properties props = new Properties();
try (InputStream is = YourClass.class.getClassLoader().getResourceAsStream("app.properties");
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
props.load(reader);
}加载失败的常见错误信号和定位方法
程序没报错但props.getProperty("xxx")返回null,大概率不是代码问题,而是资源没加载进来。
排查步骤:
- 检查
getResourceAsStream()返回是否为null——这是最常被忽略的判断 - 确认
config.properties在target/classes/(Maven)或out/production/(IntelliJ)下存在 - IDE里右键文件 → “Copy Reference”,粘贴路径到
getResourceAsStream(),避免手输错误 - 若用Spring Boot,优先用
@Value或@ConfigurationProperties,别自己造轮子
为什么不用PropertyResourceBundle?
有人看到PropertyResourceBundle觉得更“正规”,其实它只是ResourceBundle的一个实现,专为i18n设计,会强制要求key存在、自动忽略注释行、且不提供getProperty这种灵活访问方式。
除非你真在做多语言包,否则:
-
PropertyResourceBundle不能直接获取未定义key的默认值 - 它把所有值当
String转成Object再强转,出错堆栈难读 - 不支持
store()写回文件,而Properties可以
真正复杂的配置场景(嵌套、类型转换、热更新),Properties只是起点。别在它上面堆逻辑,该上Apache Commons Configuration或Typesafe Config就上。










