⛳ 如何使用 getResourceAsStream() 加载文件

加载文件目录

  • ⛳ 如何使用 getResourceAsStream() 加载文件
    • 一,简介
    • 二,示例用法
      • 2.1,不使用类加载器(`ClassLoader`)
      • 2.2,使用类加载器(`ClassLoader`)
    • 三,使用类加载器(ClassLoader)和不使用类加载器的区别
    • 四,`ClassLoader`的根路径是在哪里?

⛳ 如何使用 getResourceAsStream() 加载文件

一,简介

getResourceAsStream() 是java中用于加载资源文件的方法之一。

它是 ClassLoaderClass 类提供的方法,用于从类路径(ClassPath)中获取资源文件并返回一个输入流 (InputStream。这个方法常用于加载配置文件,模板文件,图片,音频等各种类型的资源。

方法签名:

InputStream getResourceAsStream(String name);

参数:

  • name : 表示要加载的资源文件的路径,可以是相对路径或绝对路径。对于相对路径,其起始点通常是调用 getResourceAsStream() 方法的类或类加载器的位置,需要看是YouClassName.class.getResourceAsStream()调用, 还是 YouCalssName.class.getClassLoader().getResourceAsStream()调用。具体细节看下文。

返回值:

  • 如果找到资源文件,则返回一个 InputStream 对象,允许你以字节流的方式读取资源文件的内容。
  • 如果找不到资源文件,则返回 null 。

注意事项:

  • getResourceAsStream()方法在查找资源文件时,会根据调用它的类或类加载器的位置来查找资源。如果资源文件不在相应的类路径下,可能会导致找不到资源的情况。
  • 路径参数一般以/开头表示从类路径的根目录开始查找资源,不以 / 开头表示从调用它的类所在的包路径开始查找资源。

二,示例用法

2.1,不使用类加载器(ClassLoader

// 假设要加载名为"config.properties"的配置文件
InputStream inputStream = YourClassName.class.getResourceAsStream("/config.properties");

// 使用BufferedReader读取配置文件内容
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    // 处理异常
}

注:YourClassName是当前类的类名,用于定位类路径。可以通过这种方式加载任何类型的资源文件,并以输入流的形式读取其内容,无需关心资源文件的具体位置。

2.2,使用类加载器(ClassLoader

/**
     *  zip 压缩文件部署
     * @throws IOException
     */
    @Test
    public void deployProcessByZip() throws IOException {
        // 定义zip输入流
        InputStream inputStream = this.getClass()  // getClass() 返回:表示此对象的运行时类的Class对象。
                .getClassLoader()   // 返回:装入此对象表示的类或接口的类装入器。
                .getResourceAsStream("process/process.zip");
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);

        // 流程部署
        Deployment deployment = repositoryService.createDeployment()
                .addZipInputStream(zipInputStream)
                .name("请假申请流程")
                .deploy();
        System.out.println("流程部署id: " + deployment.getId());
        System.out.println("流程部署名称:" + deployment.getName());
    }

三,使用类加载器(ClassLoader)和不使用类加载器的区别

案例:

this.getClass()  // getClass() 返回:表示此对象的运行时类的Class对象。
    .getClassLoader()   // 返回:装入此对象表示的类或接口的类装入器。
    .getResourceAsStream("process/process.zip");


this.getClass()  // getClass() 返回:表示此对象的运行时类的Class对象
    .getResourceAsStream("process/process.zip");  
  1. this.getClass().getClassLoader().getResourceAsStream("process/process.zip"): 这种方式使用类加载器(ClassLoader)来加载资源文件。类加载器是用于加载类的机制,并且每个类加载器都有自己的类加载路径。getResourceAsStream方法的路径是相对于类加载器的根路径。因此,"process/process.zip" 这个路径将相对于类加载器的根路径来定位资源文件。

    在一些情况下,特别是当使用不同的类加载器(例如自定义类加载器)加载类时,this.getClass().getClassLoader().getResourceAsStream("process/process.zip") 可能更可靠,因为它直接使用类加载器的路径,不受当前类的位置的影响。

  2. this.getClass().getResourceAsStream("process/process.zip"): 这种方式使用当前类的类加载器来加载资源文件。getResourceAsStream方法的路径是相对于当前类所在的包路径(package path)。换句话说,它会在当前类的包路径下寻找资源文件。

    这种方式适用于当前类和资源文件在同一个包路径下的情况。如果资源文件与当前类在不同的包路径下,或者资源文件位于类加载器的根路径(Classpath根目录)下,这种方式可能会失败,因为它是相对于当前类所在的包路径来定位资源文件。

所以,总的来说,两种方式都可以加载资源文件,但要根据你的具体情况来选择哪种方式更合适。如果你需要在不同类加载器的情况下加载资源文件或者资源文件位于类加载器的根路径下,推荐使用this.getClass().getClassLoader().getResourceAsStream("process/process.zip");如果资源文件与当前类在同一个包路径下,那么 this.getClass().getResourceAsStream("process/process.zip") 是更直观的选择。

当我看到这里,还是有一点不明白,在this.getClass().getClassLoader().getResourceAsStream("process/process.zip")调用中,getResourceAsStream方法的路径是相对于类加载器的根路径。那么,这个类加载的根路径是哪里呢?

四,ClassLoader的根路径是在哪里?

类加载器的根路径,也称为Classpath根路径,是类加载器用于查找类和资源文件的基本路径。在Java中,有三种主要的类加载器:

  1. Bootstrap ClassLoader(启动类加载器):
    • 它是JVM的一部分,用于加载JVM自身的核心类,如java.lang.Objectjava.lang.String等。
    • 它没有确定的文件系统路径,它是用本地代码实现的,并且通常由JVM自动加载。
  2. Extension ClassLoader(扩展类加载器):
    • 它是由sun.misc.Launcher$ExtClassLoader表示的,负责加载Java的扩展库(extensions)。
    • 它的类路径通常是${java.home}/lib/ext/目录,其中${java.home}是JDK的安装目录。
  3. System ClassLoader / Application ClassLoader(系统类加载器/应用程序类加载器):
    • 它是由sun.misc.Launcher$AppClassLoader表示的,负责加载应用程序的类和资源文件。
    • 它的类路径通常是由java.class.path系统属性指定的,包括当前工作目录和所有被指定的JAR文件或目录。

对于系统类加载器,其类路径包含了Classpath根路径。在绝大多数情况下,Classpath根路径是项目构建(如Maven或Gradle项目)的src/main/resources目录。在这个目录下的资源文件,通过getClass().getResourceAsStream()或者getClass().getClassLoader().getResourceAsStream()来访问。

请注意,类加载器可以是层次结构的,当一个类加载器无法加载类或资源时,它会委托给父类加载器来尝试加载。因此,资源的查找顺序是从下往上,即从当前类加载器的类路径开始,然后向上层级查找,直到找到资源或到达Bootstrap ClassLoader。

你可能感兴趣的:(Java基础知识,Java反射,java,开发语言)