Gradle 的文件拷贝优势在于声明式、可复用、可缓存的抽象层,而非底层I/O性能;FileCollection精确描述文件集合并支持增量判断,FileTree高效遍历过滤目录树,Copy任务内置缓冲、并发与增量校验。

Gradle 本身不提供“高性能文件拷贝”的底层引擎,它依赖 Java 的 I/O 能力,但通过 FileCollection 和 FileTree 这两个抽象层,能以声明式、可复用、可缓存的方式组织和驱动批量文件操作——这才是 Gradle 独有的优势。关键不在“快”,而在“准、稳、可复用”。
用 FileCollection 精确描述要拷贝的文件集合
FileCollection 是一组文件的逻辑容器,不关心路径来源(字符串、File 对象、List、甚至其他任务输出),只统一暴露为可迭代的 File 列表。它天然支持增量构建判断(比如跳过未变更文件)。
- 支持混合输入:路径字符串、
File实例、数组、集合都能直接传入files() - 自动解析相对路径:所有字符串路径默认相对于当前 project 目录(根项目或子模块)
- 延迟求值:直到真正遍历时才解析路径是否存在,避免提前失败
示例:
def sources = files('src/main/resources', new File('config/app.yaml'), project.fileTree(dir: 'assets', include: '**/*.png'))用 FileTree 高效遍历目录结构并过滤
FileTree 是 FileCollection 的子接口,专用于表示**带层级关系的目录树**,支持 include/exclude 模式匹配、深度限制、访问元数据(如 lastModified),比手动递归更安全、更语义化。
立即学习“Java免费学习笔记(深入)”;
- 内置 Ant 风格通配符:
**/*.jar、*.xml、!**/test/** - 可链式配置:
fileTree(dir: 'build/libs').matching { include '**/*.jar' } - 配合
visit或asMap可按需提取路径或内容,避免全量加载
注意:不要用 fileTree 做大文件读取——它只负责“列出”,不负责“搬运”。
交给 Copy 任务执行真正拷贝(而非手写 Java IO)
Gradle 推荐使用内置的 Copy 任务类型,它内部已集成缓冲、并发、增量校验(基于时间戳或内容哈希)、符号链接处理等能力,且天然兼容构建缓存。
- 输入源用
from接收任意FileCollection或FileTree - 目标用
into指定目录,支持重命名、过滤、内容变换(expand、filter) - 无需手动打开流、关流、异常捕获——这些都由 Gradle 自动保障
示例:
tasks.register('copyAssets', Copy) {from sources
into layout.buildDirectory.dir('dist/assets')
includeEmptyDirs = false
}
避免常见性能陷阱
所谓“高性能”,更多来自规避低效写法,而非追求极致吞吐:
- 别在
doLast里用new FileInputStream手动逐文件拷贝——失去增量判断、缓存、并行能力 - 别用
file.text = ...写大文件——它会把整个内容加载进内存,适合小文本,不适合二进制或 MB 级文件 - 慎用
fileTree().files全量转 List——对深层目录可能触发大量磁盘扫描;优先用eachFile或visit流式处理 - 绝对路径尽量少用——破坏构建可移植性;如必须,确保跨平台(用
File.separator或Paths.get())



















