杰瑞科技汇

Java properties文件读取方式有哪些?

下面我将为你详细介绍几种主流的读取 Properties 文件的方法,从最传统到最现代,并附上完整的代码示例。

Java properties文件读取方式有哪些?-图1
(图片来源网络,侵删)

使用 java.util.Properties 类(最传统、最基础)

这是最经典、最直接的方法,适用于所有 Java 版本,核心思想是使用 InputStream 读取文件,然后加载到 Properties 对象中。

核心步骤:

  1. 获取文件输入流 (InputStream)
    • 使用 ClassLoader:这是最推荐的方式,因为它会从 classpath(类路径)下查找文件,无论是从 JAR 包运行还是从 IDE 运行都适用。
    • 使用 FileInputStream:直接从文件系统读取路径,灵活性较低,且需要处理绝对/相对路径问题。
  2. 加载文件内容:调用 properties.load(inputStream) 方法。
  3. 关闭流:使用 try-with-resources 语句确保 InputStream 被正确关闭,防止资源泄漏。
  4. 获取属性值:使用 properties.getProperty("key") 方法。

示例代码

假设你的项目结构如下:

my-project/
├── src/
│   └── main/
│       ├── java/
│       │   └── com/
│       │       └── example/
│       │           └── Main.java
│       └── resources/
│           └── config.properties

config.properties 文件内容:

# Database Configuration
db.url=jdbc:mysql://localhost:3306/mydb
db.username=root
db.password=secret
db.driver=com.mysql.cj.jdbc.Driver
# Application Settings
app.name=My Cool App
app.version=1.0.0

Main.java 代码:

Java properties文件读取方式有哪些?-图2
(图片来源网络,侵删)
package com.example;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesReader {
    public static void main(String[] args) {
        // 1. 创建 Properties 对象
        Properties properties = new Properties();
        // try-with-resources 确保 InputStream 被自动关闭
        // 使用 ClassLoader 从 classpath 下加载文件
        try (InputStream input = PropertiesReader.class.getClassLoader().getResourceAsStream("config.properties")) {
            if (input == null) {
                System.out.println("Sorry, unable to find config.properties");
                return;
            }
            // 2. 加载 properties 文件内容
            properties.load(input);
            // 3. 获取并打印属性值
            System.out.println("Database URL: " + properties.getProperty("db.url"));
            System.out.println("Database User: " + properties.getProperty("db.username"));
            System.out.println("Database Password: " + properties.getProperty("db.password"));
            System.out.println("App Name: " + properties.getProperty("app.name"));
            System.out.println("App Version: " + properties.getProperty("app.version"));
            // 如果属性不存在,可以提供默认值
            System.out.println("Debug Mode: " + properties.getProperty("debug.mode", "false"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

关键点说明:

  • PropertiesReader.class.getClassLoader().getResourceAsStream("config.properties"):这行代码会去 src/main/resources 目录下寻找 config.properties 文件。
  • 编码问题:默认情况下,Properties.load(InputStream) 使用 ISO-8859-1 编码读取,如果你的 .properties 文件包含中文等非 ASCII 字符,可能会乱码,解决方法是指定编码:
    // 使用 InputStreamReader 指定 UTF-8 编码
    try (InputStream input = ...;
         Reader reader = new InputStreamReader(input, StandardCharsets.UTF_8)) {
        properties.load(reader);
    }

使用 java.util.ResourceBundle 类(国际化场景)

ResourceBundle 是专门为国际化(i18n)设计的类,它不直接读取文件,而是根据不同的 Locale(语言环境)来加载对应的资源文件,对于简单的配置读取,它也是一个不错的选择。

文件命名规则:

  • 基础文件名:messages (可以自定义)
  • 语言和国家代码:messages_en_US.properties, messages_zh_CN.properties
  • 默认文件:messages.properties (当没有匹配的 Locale 时使用)

示例代码

假设资源文件名为 messages.properties,放在 src/main/resources 下。

messages.properties 文件内容:

Java properties文件读取方式有哪些?-图3
(图片来源网络,侵删)
greeting=Hello
farewell=Goodbye

Main.java 代码:

package com.example;
import java.util.Locale;
import java.util.ResourceBundle;
public class ResourceBundleReader {
    public static void main(String[] args) {
        // 1. 获取默认的 ResourceBundle (会加载 messages.properties)
        ResourceBundle defaultBundle = ResourceBundle.getBundle("messages");
        System.out.println("Default Greeting: " + defaultBundle.getString("greeting"));
        // 2. 获取指定 Locale 的 ResourceBundle (美国英语)
        // 假设存在 messages_en_US.properties
        ResourceBundle usBundle = ResourceBundle.getBundle("messages", Locale.US);
        System.out.println("US Greeting: " + usBundle.getString("greeting"));
        // 3. 获取另一个 Locale 的 ResourceBundle (简体中文)
        // 假设存在 messages_zh_CN.properties
        ResourceBundle cnBundle = ResourceBundle.getBundle("messages", Locale.SIMPLIFIED_CHINESE);
        // System.out.println("CN Greeting: " + cnBundle.getString("greeting")); // 如果文件不存在,会抛出 MissingResourceException
        // 4. 获取父 Bundle (当指定 Locale 的文件不存在时)
        // 如果 messages_zh.properties 不存在,会回退到 messages.properties
        ResourceBundle fallbackBundle = ResourceBundle.getBundle("messages", new Locale("zh"));
        System.out.println("Fallback Greeting: " + fallbackBundle.getString("greeting"));
    }
}

优点:

  • 天然支持国际化。
  • 性能更好,ResourceBundle 会被缓存。

缺点:

  • 文件名有固定格式,不够灵活。
  • 不支持动态修改,因为内容是缓存的。

使用 Spring Framework 的 @Value 注解(在 Spring/Spring Boot 项目中)

如果你正在使用 Spring 或 Spring Boot 框架,这是最方便、最优雅的方式,它允许你直接将配置文件的值注入到字段中。

在 Spring Boot 中:

Spring Boot 默认会加载 application.propertiesapplication.yml 文件,你可以在任何被 Spring 管理的 Bean(即带有 @Component, @Service, @Controller 等注解的类)中使用。

application.properties 文件内容:

app.name=Spring Boot App
app.version=2.7.0

MyService.java 代码:

package com.example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class MyService {
    @Value("${app.name}")
    private String appName;
    @Value("${app.version}")
    private String appVersion;
    public void printAppInfo() {
        System.out.println("App Name from @Value: " + appName);
        System.out.println("App Version from @Value: " + appVersion);
    }
}

MainApplication.java (启动类):

package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(MainApplication.class, args);
        MyService myService = context.getBean(MyService.class);
        myService.printAppInfo();
    }
}

在传统 Spring 项目中:

你需要配置一个 PropertyPlaceholderConfigurer 来指定你的 properties 文件位置。

<!-- 在 XML 配置文件中 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:config.properties"/>
</bean>
<bean id="myService" class="com.example.MyService"/>

总结与对比

方法 优点 缺点 适用场景
java.util.Properties 标准Java库,不依赖框架。
灵活,可读取任意路径的文件。
可动态修改和重新加载。
需要手动管理资源流(尽管 try-with-resources 很方便)。
处理编码问题稍显麻烦。
纯Java项目(非Spring)。
需要动态加载配置。
作为基础工具类使用。
java.util.ResourceBundle 性能好,内容被缓存。
天然为国际化设计
分享:
扫描分享到社交APP
上一篇
下一篇