Kotlin中File.copyRecursively的onError参数配置与异常处理方法
Kotlin
File.copyRecursively 方法的 onError 参数编写指南 你现在的调用代码只传入了overwrite = true参数,没有自定义异常处理的话,会走默认的onError逻辑:一旦复制过程遇到IO异常,就直接把异常向上抛出,中断整个复制流程。
要自定义异常处理逻辑,首先得明确onError lambda的规则:
- 它的两个入参分别是复制过程中出错的源文件对象、捕获到的IO异常实例
- 它必须返回一个
OnErrorAction枚举值,告诉方法出错后要执行的动作,这个枚举一共有三个可选项:OnErrorAction.SKIP:跳过当前出错的文件/目录,继续处理队列里剩下的内容,不中断整体复制OnErrorAction.TERMINATE:立刻终止整个递归复制流程,不再处理后续条目OnErrorAction.THROW:把捕获到的异常直接向上抛出,交给外层代码处理(也是官方默认的行为)
常见的自定义写法示例
1. 单文件出错就记日志跳过,不中断整体复制
最常用的场景是批量复制时,遇到个别文件权限不足、被占用的问题,不想让整个流程因为单个文件失败就崩:
val dest = File(filePath) source.copyRecursively( target = dest, overwrite = true, onError = { errorFile, ioException -> // 在这里加你自己的日志、埋点逻辑 println("跳过复制失败的文件:${errorFile.absolutePath},原因:${ioException.message}") return@copyRecursively OnErrorAction.SKIP } )
2. 收集所有错误,复制完成后统一反馈
如果你需要给用户返回完整的失败列表,可以在外部定义一个错误集合,在onError回调里把失败的条目存进去:
// 外部定义错误收集容器 val failedFiles = mutableListOf<Pair<File, IOException>>() val dest = File(filePath) val copyResult = source.copyRecursively( target = dest, overwrite = true, onError = { errorFile, ioException -> failedFiles.add(errorFile to ioException) OnErrorAction.SKIP } ) // 复制流程结束后,根据结果做后续处理 if (failedFiles.isNotEmpty()) { println("复制完成,共${failedFiles.size}个文件复制失败") }
3. 按异常类型区分处理策略
你也可以在回调里判断异常类型,遇到严重错误(比如磁盘满、目标路径不存在)就直接终止,小问题就跳过:
val dest = File(filePath) source.copyRecursively( target = dest, overwrite = true, onError = { errorFile, ioException -> when (ioException) { is FileSystemFullException -> { // 磁盘空间不足,没法继续复制,直接终止 println("磁盘空间不足,终止复制流程") OnErrorAction.TERMINATE } else -> { // 其他单文件类错误(权限不足、文件被锁等)直接跳过 println("跳过失败文件:${errorFile.name}") OnErrorAction.SKIP } } })
注意事项
- 回调里的第一个参数是出问题的源文件,不是复制后的目标文件,不要搞混两个路径的指代
- onError回调里一定要返回合法的
OnErrorAction值,不能无返回,否则方法无法判断后续处理逻辑 - 如果你希望保持默认的“遇到错误就抛出中断”的行为,完全不需要显式传入onError参数,和你现有代码的运行效果完全一致
内容的提问来源于stack exchange,提问作者andoryu a
相关产品推荐
相关产品推荐

