最近一直在做自己的代码生成器项目,遇到一个需求,需要把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
于是便有了以下思路
- 获取Jar包某些文件夹下所有文件的流
- 筛选需要复制的流
- 复制
代码如下
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。