其他分享
首页 > 其他分享> > springboot项目部署之后如何读取到Resource(ClassPath)下的资源

springboot项目部署之后如何读取到Resource(ClassPath)下的资源

作者:互联网

文章目录

1. 前提说明

  1. 一般写代码读取io文件的时候,路径可以写相对路径以及绝对路径,在开发环境下,没有什么所谓。
  2. 但部署项目的时候,路径选择使用绝对路径是更加优的选择。
  3. 比如打包项目,会将项目打包成Jar包或者war包,此时就不会存在 src/main/resources 目录,JVM会在编译项目时,主动将 java文件编译成 class文件 和 resources 下的静态文件放在 target/classes目录下。
  4. 那么将如何获取在Resource下的资源文件呢。

2. 获取Resource下资源文件的方法

  1. ClassPathResource方法。
  2. 使用getResourceStream方法,本质使用类加载器classloader,分别为this.class.getResourceStream 与 this.class.getClassloader.getResourceStream。

3. ClassPathResource使用

  1. ClassPathResource 默认是读取Resource(classpath)下的文件

  2. 先创建一个文件,如下图:
    在这里插入图片描述

  3. 代码

    public class ClassPathResource_Test {
        public static void main(String[] args) {
            // ClassPathResource 读取文件
            ClassPathResource classPathResource = new ClassPathResource("ReadResourceFile.txt");
            // 获取输入流
            try (InputStream inputStream = classPathResource.getInputStream()) {
                int len;
                byte[] buffer = new byte[1024];
                while ((len = inputStream.read(buffer)) != -1) {
                    System.out.println(new String(buffer, 0, len));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    结果:
    我是在resources的文件
    

3. 使用getResourceStream获取,本质是类加载器classloader

0. 前提须知,如何将src/main/java下的资源进行打包到target中

  1. 因为Class.getResourceAsStream中变量path 不以’/'开头时默认是从此类所在的包下取资源,而springboot项目默认不打包src下除了.java的其他文件,为了测试下面,因此我们需要设置,让其允许其他资源打包。
  2. https://blog.csdn.net/xueyijin/article/details/121441448

1. this.class.getResourceStream

  1. Class.getResourceAsStream(String path) :

    1. path 不以’/'开头时默认是从此类所在的包下取资源
    2. 以’/'开头则是从 ClassPath根下获取。
    3. 最终还是由ClassLoader获取资源。
  2. 代码
    准备两个文件,一个在类所在包下,一个在resource资源下。
    在这里插入图片描述
    不加 / 的情况:

    public class Class_getResourceAsStream {
        public static void main(String[] args) {
            // 不加 / 是从当前类所在包下获取资源
            try (InputStream in = Class_getResourceAsStream.class.getResourceAsStream("ReadResourceFile.txt")) {
                // 加 / 是从classPath下加载资源
                // InputStream in = Class_getResourceAsStream.class.getResourceAsStream("/ReadResourceFile.txt")
                byte[] bytes = new byte[1024];
                int len;
                while ((len = in.read(bytes)) != -1) {
                    System.out.println(new String(bytes, 0, len));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在这里插入图片描述

    加 / 的情况:
    在这里插入图片描述

2. 为什么this.class.getResourceStream也是使用类加载器

根据源码所示:

	// 在Class类中
     public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        // 这里调用了getClassLoader0
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
    }
	// 可得其实在Class类中,有个成员变量是保存classLoader
	ClassLoader getClassLoader0() { 
		return classLoader; 
	}

3. this.class.getClassloader.getResourceStream

  1. Class.getClassLoader.getResourceAsStream(String path) : 默认则是从ClassPath根下获取path不能以’/'开头,最终是由 ClassLoader获取资源。

  2. 代码:

    public class Classloader_getResourceStream_Test {
        public static void main(String[] args) {
            try (InputStream in = Class_getResourceAsStream.class.getClassLoader().getResourceAsStream("ReadResourceFile.txt")) {
                byte[] bytes = new byte[1024];
                int len;
                while ((len = in.read(bytes)) != -1) {
                    System.out.println(new String(bytes, 0, len));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在这里插入图片描述

标签:getResourceAsStream,Resource,springboot,ClassPath,len,Class,getResourceStream,cl
来源: https://blog.csdn.net/xueyijin/article/details/121441738