读取 Resource 目录下文件内容

getResource()getResourceAsStream() 方法之间的区别

在 Java 开发中,getResource()getResourceAsStream() 是两个常用的类加载器方法,用于从类路径中加载资源。然而,它们在功能和使用场景上存在显著差异。本文将详细探讨这两种方法的区别,并提供使用建议。

1. 方法概述

getResource()

  • 返回值 :返回一个 URL 对象,表示资源的路径。

  • 用途:用于获取资源的路径信息,通常用于需要解析资源路径的场景。

  • 返回路径格式

    • 如果资源位于文件系统中,返回的路径格式为 file:/path/to/resource

    • 如果资源被打包在 JAR 文件中,返回的路径格式为 jar:file:/path/to/jar!/resource

getResourceAsStream()

  • 返回值 :返回一个 InputStream,直接提供对资源内容的访问。

  • 用途:用于直接读取资源内容,适用于需要处理资源数据的场景。

  • 特点:无论资源位于文件系统中还是打包在 JAR 文件中,都能直接读取资源内容,无需解析路径。

2. 区别

2.1 路径解析

  • getResource()

    • 返回的路径是一个 URL,可能包含特殊字符(如 !%),不能直接用作文件路径。

    • 如果资源位于 JAR 文件中,返回的路径是 jar: 协议的 URL,无法直接访问文件系统。

  • getResourceAsStream()

    • 直接返回一个 InputStream,无需解析路径。

    • 更通用、更可靠,适用于所有资源加载场景。

2.2 使用场景

  • getResource()

    • 适用于需要获取资源路径的场景,例如动态加载配置文件或解析资源路径。

    • 如果资源位于文件系统中,可以通过 URL.toURI() 转换为 File 对象。

  • getResourceAsStream()

    • 适用于需要直接读取资源内容的场景,例如读取文本文件、配置文件或二进制资源。

    • 更适合处理打包在 JAR 文件中的资源。

2.3 示例代码

使用 getResource()

java复制

复制代码
URL resourceUrl = BackendApplication.class.getClassLoader().getResource("prompt/一号风电场0303风速.csv");
if (resourceUrl != null) {
    System.out.println("资源路径: " + resourceUrl);
    if ("file".equals(resourceUrl.getProtocol())) {
        File file = new File(resourceUrl.toURI());
        // 使用 file 进行操作
    } else {
        System.out.println("资源位于 JAR 文件中,无法直接访问路径。");
    }
} else {
    System.out.println("资源未找到!");
}
使用 getResourceAsStream()

java复制

复制代码
InputStream inputStream = BackendApplication.class.getClassLoader().getResourceAsStream("prompt/一号风电场0303风速.csv");
if (inputStream != null) {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
} else {
    System.out.println("资源未找到!");
}

3. 为什么 getResource().getPath() 不能直接读取文件数据?

当你调用 getResource().getPath() 时,返回的路径是一个 URL 编码的字符串,可能包含特殊字符(如 !%)。如果资源位于 JAR 文件中,返回的路径格式为:

jar:file:/path/to/your.jar!/BOOT-INF/classes!/prompt/一号风电场0303风速.csv

这种路径不能直接用作文件路径,因为它是一个 jar: 协议的 URL,而不是标准的文件路径。因此,尝试直接使用 File 类访问这种路径会导致失败。

4. 为什么 getResourceAsStream() 能读取数据?

getResourceAsStream() 直接返回一个 InputStream,封装了对资源内容的访问。它不需要解析路径,也不需要将资源路径转换为文件路径。因此,无论资源位于文件系统中还是打包在 JAR 文件中,getResourceAsStream() 都可以直接读取资源内容,更通用、更可靠。

5. 使用建议

5.1 如果需要读取资源内容

推荐使用 getResourceAsStream(),因为它更通用、更可靠。例如:

java复制

复制代码
InputStream inputStream = BackendApplication.class.getClassLoader().getResourceAsStream("prompt/一号风电场0303风速.csv");
if (inputStream != null) {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
} else {
    System.out.println("资源未找到!");
}

5.2 如果需要获取资源路径

可以使用 getResource(),但需要正确处理返回的 URL。例如:

java复制

复制代码
URL resourceUrl = BackendApplication.class.getClassLoader().getResource("prompt/一号风电场0303风速.csv");
if (resourceUrl != null) {
    System.out.println("资源路径: " + resourceUrl);
    if ("file".equals(resourceUrl.getProtocol())) {
        File file = new File(resourceUrl.toURI());
        // 使用 file 进行操作
    } else {
        System.out.println("资源位于 JAR 文件中,无法直接访问路径。");
    }
} else {
    System.out.println("资源未找到!");
}

6. 总结

  • getResource() :返回一个 URL,适用于需要解析资源路径的场景。

  • getResourceAsStream() :返回一个 InputStream,适用于需要直接读取资源内容的场景。

  • 如果需要读取资源内容,推荐使用 getResourceAsStream()

  • 如果需要获取资源路径,可以使用 getResource(),但需要正确处理返回的 URL。

相关推荐
程序员cxuan20 分钟前
为啥 Blender 突然火了?
人工智能·后端·程序员
IT_陈寒34 分钟前
React的状态更新竟然不是同步的?!坑了我一整天
前端·人工智能·后端
必须会一定会1 小时前
Spring Boot 3 + PostgreSQL 场景工程持久化:revision、contentHash 与历史回滚
人工智能·spring boot·后端·postgresql·ai编程
object not found1 小时前
Nuxt4去掉body中默认的边距
开发语言·后端·rust
zzzll11113 小时前
Spring Boot 实现数据脱敏:自定义注解 + Jackson 序列化器
java·spring boot·后端
vx-Biye_Design7 小时前
SSM伴侣动物伴护星小程序06330-计算机课程设计、毕业设计
spring boot·后端·elasticsearch·小程序·架构·课程设计·idea
2分钟速写快排9 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
面向Google编程9 小时前
Apache Iceberg Variant 类型:v3 半结构化数据不再「二选一」
大数据·后端
jason成都10 小时前
Spring WebFlux 适配达梦新方案|dm‑r2dbc:Netty 异步传输的实验性 R2DBC 驱动
java·后端·spring
北岛贰11 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端