下面我将详细介绍几种读写 properties 文件的方法,从最基础到更现代和推荐的方式。

java.util.Properties 类
这是 Java 标准库中专门用于处理 .properties 文件的类,它继承自 Hashtable<Object, Object>,因此除了基本的读写功能,它还具备了 Map 的所有特性。
1 写入 Properties 文件
我们可以使用 Properties.store() 方法将配置写入到一个 .properties 文件中。
示例代码:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class PropertiesWriterExample {
public static void main(String[] args) {
// 1. 创建 Properties 对象
Properties properties = new Properties();
// 2. 设置键值对
properties.setProperty("database.url", "jdbc:mysql://localhost:3306/mydb");
properties.setProperty("database.user", "admin");
properties.setProperty("database.password", "secret123");
properties.setProperty("server.port", "8080");
properties.setProperty("app.name", "My Java Application");
// 3. 指定输出文件路径
String filePath = "config.properties";
// try-with-resources 语句确保 OutputStream 被正确关闭
try (OutputStream output = new FileOutputStream(filePath)) {
// 4. 将 properties 保存到文件
// 第一个参数是 OutputStream
// 第二个参数是写入文件时的注释(可选)
properties.store(output, "Application Configuration File");
System.out.println("Properties file saved successfully at: " + filePath);
} catch (IOException e) {
System.err.println("Error writing properties file: " + e.getMessage());
e.printStackTrace();
}
}
}
执行后,config.properties 文件内容如下:

#Application Configuration File #Mon Nov 20 10:30:00 CST 2025 database.url=jdbc:mysql://localhost:3306/mydb database.user=admin database.password=secret123 server.port=8080 app.name=My Java Application
2 读取 Properties 文件
我们可以使用 Properties.load() 方法从一个 .properties 文件中加载配置。
示例代码:
假设 config.properties 文件存在,内容如上。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesReaderExample {
public static void main(String[] args) {
// 1. 创建 Properties 对象
Properties properties = new Properties();
// 2. 指定输入文件路径
String filePath = "config.properties";
// try-with-resources 语句确保 InputStream 被正确关闭
try (InputStream input = new FileInputStream(filePath)) {
// 3. 从输入流中加载 properties
properties.load(input);
// 4. 读取并打印配置项
System.out.println("Database URL: " + properties.getProperty("database.url"));
System.out.println("Database User: " + properties.getProperty("database.user"));
System.out.println("Server Port: " + properties.getProperty("server.port"));
System.out.println("App Name: " + properties.getProperty("app.name"));
// 使用 getProperty(key, defaultValue) 可以提供默认值
String debugMode = properties.getProperty("debug.mode", "false");
System.out.println("Debug Mode: " + debugMode);
} catch (IOException e) {
System.err.println("Error reading properties file: " + e.getMessage());
e.printStackTrace();
}
}
}
输出:

Database URL: jdbc:mysql://localhost:3306/mydb
Database User: admin
Server Port: 8080
App Name: My Java Application
Debug Mode: false
从资源目录中读取 Properties 文件
在实际的 Java 项目中,配置文件通常放在 src/main/resources 目录下(对于 Maven/Gradle 项目),这些文件会被打包到最终的 JAR 或 WAR 文件的根目录中,我们不能使用 FileInputStream,因为它依赖于文件系统路径,而应该使用 ClassLoader 来从类路径(Classpath)中读取资源。
示例代码:
假设 config.properties 在 src/main/resources 目录下。
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesResourceReaderExample {
public static void main(String[] args) {
Properties properties = new Properties();
// 使用 / 开头表示从类路径的根目录开始查找
String resourcePath = "/config.properties";
// try-with-resources
try (InputStream input = PropertiesResourceReaderExample.class.getResourceAsStream(resourcePath)) {
if (input == null) {
System.err.println("Sorry, unable to find " + resourcePath);
return;
}
properties.load(input);
// 打印所有加载的属性
properties.list(System.out);
} catch (IOException e) {
System.err.println("Error reading properties from resource: " + e.getMessage());
e.printStackTrace();
}
}
}
关键点:
getClass().getResourceAsStream(String name):name以 开头时,表示从类路径的根目录查找,否则,从当前类的包路径下查找。- 这种方式的优势在于,无论你的应用是作为 JAR 运行还是部署在服务器上,都能正确找到资源文件。
处理中文乱码问题
标准的 properties 文件是 ISO-8859-1 编码的,如果直接写入中文,读取时会出现乱码。
写入中文乱码的例子:
properties.setProperty("welcome.message", "你好,世界!");
properties.store(output, null);
// config.properties 文件中会显示为 welcome.message=\u4F60\u597D\uFF0C\u4E16\u754C\uFF01
读取时是没问题的,因为 Java 会自动处理 \uXXXX 转义,但如果希望文件中直接显示可读的中文,就需要指定编码。
解决方案:使用 OutputStreamWriter 和 InputStreamReader
我们可以通过指定字符编码来读写文件,避免乱码。
写入中文(指定编码):
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class PropertiesWriterWithEncoding {
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("welcome.message", "你好,世界!");
properties.setProperty("greeting", "Hello, 世界!");
String filePath = "config_chinese.properties";
try (OutputStream output = new FileOutputStream(filePath);
// 使用 OutputStreamWriter 指定编码为 UTF-8
OutputStreamWriter writer = new OutputStreamWriter(output, StandardCharsets.UTF_8)) {
// 在 store 方法中,我们传入的是 Writer 而不是 OutputStream
// 并且可以指定一个注释,以及是否将键和值都进行转义
properties.store(writer, "Configuration with Chinese characters");
System.out.println("Properties file with Chinese saved successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
config_chinese.properties 文件内容(UTF-8编码):
#Configuration with Chinese characters #Mon Nov 20 10:35:00 CST 2025 welcome.message=\u4F60\u597D\uFF0C\u4E16\u754C\uFF01 greeting=Hello, \u4E16\u754C\uFF01
注意: 即使指定了UTF-8写入,store方法为了兼容性,默认还是会将非ASCII字符转义,如果希望直接写入中文,需要一些额外的处理,或者使用第三方库,对于大多数场景,Java自动的\uXXXX转义是标准且安全的。
读取中文(指定编码):
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class PropertiesReaderWithEncoding {
public static void main(String[] args) {
Properties properties = new Properties();
String filePath = "config_chinese.properties";
try (InputStream input = new FileInputStream(filePath);
// 使用 InputStreamReader 指定编码为 UTF-8
InputStreamReader reader = new InputStreamReader(input, StandardCharsets.UTF_8)) {
properties.load(reader);
System.out.println("Welcome Message: " + properties.getProperty("welcome.message"));
System.out.println("Greeting: " + properties.getProperty("greeting"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
更现代的方式:java.util.Properties 与 InputStream 的结合(Java 9+)
从 Java 9 开始,Properties 类新增了 load(InputStream in) 的重载方法,可以直接指定字符编码,简化了代码。
读取(Java 9+):
// ...
try (InputStream input = new FileInputStream("config_chinese.properties")) {
// 直接指定编码加载
properties.load(input, StandardCharsets.UTF_8);
// ...
}
// ...
这个方法比手动创建 InputStreamReader 更简洁,是推荐的现代写法。
总结与最佳实践
| 场景 | 推荐方法 | 关键代码/说明 |
|---|---|---|
| 写入配置文件 | Properties.store(OutputStream, comments) |
使用 try-with-resources 确保 FileOutputStream 关闭,文件编码默认为 ISO-8859-1,中文会转义。 |
| 从文件系统读取 | Properties.load(InputStream) |
使用 try-with-resources 确保 FileInputStream 关闭。 |
| 从资源目录读取 | getClass().getResourceAsStream("/path/to/file.properties") |
适用于 JAR/WAR 包中的资源,与部署环境无关。 |
| 处理中文 | 写入: OutputStreamWriter + UTF-8 读取: InputStreamReader + UTF-8 (Java 9+) properties.load(input, StandardCharsets.UTF_8) |
关键:必须确保读写使用相同的编码(推荐 UTF-8)。 |
| 最佳实践 | 将配置文件放在 src/main/resources。使用 getResourceAsStream 从类路径读取。使用 try-with-resources 管理 I/O 流。为 getProperty() 方法提供默认值,增强程序的健壮性。 |
String port = properties.getProperty("server.port", "8080"); |
通过以上方法,你可以灵活、健壮地在 Java 应用程序中处理 properties 配置文件。
