Jar包内资源复制问题

Posted by zsh on December 3, 2020

最近一直在做自己的代码生成器项目,遇到一个需求,需要把resources文件夹下的某些文件夹按照原本的文件结构,复制到Jar包外的另一处位置。 一开始在IDEA里开发觉得很简单,就一句FileUtils.copyDirectory(src, dest)就万事了,IDEA运行也很顺利,文件都按照预想的复制过去了,然后我准备打包部署到服务器上试一下, 这一试就试出问题了,直接抛了异常如下 class path resource xxx cannot be resolved to absolute file path because it does not reside in the file system 谷歌了一下,才知道Jar包里的文件是不能被当作文件系统里的文件来处理的,而只能用流的方式去处理。但试了一圈也没发现有什么简单的方法可以把Jar包下某个文件夹的流复制到Jar包外, 不过倒是让我找到FileUtils.copyURLToFile(url, file),按着这个方法找到了一个思路: 不关心文件夹,而是把文件夹下的文件独立地通过流复制到目的地。 spring本身有许多方便的方法去处理ClassPathResource,通过ClassPathResource可以拿到对应的InputStream 于是便有了以下思路

  1. 获取Jar包某些文件夹下所有文件的流
  2. 筛选需要复制的流
  3. 复制 代码如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
     // 通过spring提供的方法,用匹配路径字符串获取需要复制的resources
     val resourceResolver = PathMatchingResourcePatternResolver()
     val resources = resourceResolver.getResources("/templates/layui/**")
     resources.filter { ReUtil.isMatch(".*?\\.[a-zA-Z]*?", it.filename!!) } // 进一步筛选需要复制哪些文件,同时过滤掉文件夹路径的resource
         .forEach {
             val url = it.url
             val filePath = url.path.substring(url.path.indexOf("layui") + 5)
             if (!filePath.contains("page")) {
                 val destination = File("${pathConstant.resourcesDirPath()}/templates/$filePath")
                 FileUtils.copyURLToFile(url, destination) // 复制
             }
         }
    

最后打包测试,一切OK。