如何通过Groovy(Gradle)仅在目标目录无对应文件时复制文件
在Gradle中实现「仅复制不存在的文件」的几种方法
嘿,这个需求我之前也碰到过,Gradle里确实有几种靠谱的实现方式,不用自己写复杂的判断逻辑,我给你梳理下:
方法一:用Gradle原生Copy任务配合文件过滤
Gradle的Copy任务本身支持通过eachFile方法对每个待复制的文件做判断,我们可以在这里检查目标路径是否存在,存在就跳过该文件。示例代码如下:
task copyFilesWithoutOverwriting(type: Copy) { // 源文件目录/路径 from 'src/main/resources/configs' // 目标目录 into 'build/output/configs' // 对每个待复制文件做判断 eachFile { fileDetails -> def targetFile = new File(destinationDir, fileDetails.path) // 如果目标文件已存在,就排除这个文件(不复制) if (targetFile.exists()) { fileDetails.exclude() } } // 可选:如果不需要创建空目录,把这个设为false includeEmptyDirs = false }
如果是在已有任务的CopySpec里(比如你原来用的from(source){ into destination }这种写法),也可以直接嵌入这个逻辑:
// 假设你在processResources任务里嵌入了Copy逻辑 processResources { from 'src/main/resources' { into 'META-INF' eachFile { fd -> def target = new File(destinationDir, fd.path) if (target.exists()) fd.exclude() } } }
方法二:调用Ant的Copy任务(更简洁)
因为Gradle可以直接复用Ant的任务,而Ant的copy命令原生支持overwrite="false"参数,一行就能搞定不覆盖的需求,代码更简洁:
task copyWithAnt(type: Task) { doLast { ant.copy( src: 'src/main/resources/configs', dest: 'build/output/configs', overwrite: false, // 可选:如果需要复制子目录,加上includeEmptyDirs="true" includeEmptyDirs: true ) } }
这个方法的好处是不用自己写文件存在性判断,Ant已经帮我们封装好了逻辑,适合快速实现需求。
补充说明
- 如果你需要更精细的控制(比如根据文件修改时间判断是否复制),还可以在
eachFile里对比源文件和目标文件的最后修改时间,只复制更新的文件,但你的需求是「仅当目标不存在时复制」,上面两种方法就足够了。 - 注意
destinationDir是Copy任务的内置属性,指向你指定的into目录,所以在eachFile里可以直接用它来构造目标文件路径。
内容的提问来源于stack exchange,提问作者Ali Ebrahiminejad
相关产品推荐
相关产品推荐

