欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【问题解决】解决项目打包成jar包,部署上线后,读取resources目录文件资源失效。

程序员文章站 2022-05-04 16:51:41
...

项目打包成jar包,部署上线后,读取resources目录文件资源失效。

最近在做的一个项目需要,读取模板文件和一些静态资源文件来生成对应的pdf文档。这里涉及到了很多文件读取的细节问题。

刚开始我觉得还是挺简单的吧,资源文件的读取方式有很多,这里随便列举几个:

  1. 通过ClassPathResource

    ClassPathResource resource = new ClassPathResource("对应resources目录文加下的路径");
    InputStream in = classPathResource.getInputStream();
    

    这种方法可以以流的形式读取到resources目录中的资源文件。项目打包成jar包过后同样可以

  2. 通过类加载器

    //注:这里对应的路径是java文件编译过后的目录,也就是对应到target中的classes路径下的资源(绝对路径)。这里有个坑,因为项目在打包成jar包过后,是一个压缩包,而读取的方式会变成jar!filename 这样的形式去读取文件
    this.getClass().getResource("获取的资源名称/路径").getPath();
    

    部署后报错,找不到对应的文件

    java.io.FileNotFoundException:/usTr/local/tool/weatherldatacenter. jar!/BO0T-INF/classes!/static/logo.png (Mo such file or directory)
    
  3. Java自带工具类ResourcesUtils

    以文件流的形式读取文件,但这种方法在部署过后同样会报FileNotFoundException

    File file = ResourceUtils.getFile("classpath:static/xxx.xxx");
    InputStream in = new FileInputStream(file);
    
  4. 万能方法,NB轰轰

    前面说到的几种方法,在项目部署后或多或少存在一定的问题,但这种不论是本地还是上线后都可以。并且维护性极强。所用到的主要是File.createTempFile创建临时文件,然后通过Java自带工具类FileUtils.copyInputStreamToFile(InputStream source, File destination)方法将流转为Fi文件

    之所以可以这么做的原因就是,我们可以通过ClassPathResource类以流的形式读取到resources的资源目录文件,在读取到之后,使用FileUtils进行转换。完事过后把临时文件给删了(工具人石锤了)就行了

    批话就不多说了,上代码

    public class Test {
        public static void main(String[] args){
            String resPath = "resources下的路径";
            //获取指定路径下的资源文件
            ClassPathResources resources = new ClassPathResources(resPath);
            //获取流
            InputStream in = resources.getInputStream();
            //创建临时文件(空文件)  prefx:logo  suffix: .png,该文件会默认创建在你用户的更目录下,具体哪个自己打印出来看看就知道
            File imgFile = File.createTempFile("logo", ".png");
            //将获取的流转为文件,在转换过后我们的资源文件就被copy到前面创建的临时文件中了
            FileUtils.copyInputStreamToFile(in, imgFile);
            System.out.println("临时文件路径:"+imgFile.getAbsolutePath());
            
            //不管啥环境都可以这样做。有了资源路径还不会调用么,接下来的操作无非就是读,写,改了
        }
    }