R批量下载CMIP6数据:跳过已存在文件、处理超时避免程序中断
CMIP6批量下载代码优化方案
针对提出的两个功能需求,在原有代码基础上做最小修改即可实现,优化后的代码如下:
#install.packages("epwshiftr") library("epwshiftr") # 索引CMIP6数据集元信息 test = init_cmip6_index(activity = "CMIP", variable = 'pr', frequency = 'day', experiment = c("historical"), source = NULL, years= c(1981,1991,2001,2014), variant = "r1i1p1f1" , replica = F, latest = T, limit = 10000L,data_node = NULL, resolution = NULL ) # 调整全局下载超时时间(单位:秒,默认60秒容易导致大文件超时,这里设为10分钟) options(timeout = 600) # 初始化下载失败日志 failed_list <- c() ntest <- nrow(test) for(i in 1:ntest){ url <- test$file_url[i] # 保持和原有命名规则完全一致,匹配已下载的文件 destfile <- paste0("D:/CMIP6 data/Data/", test$source_id[i], "-", test$experiment_id[i], "-", test$member_id[i], "-", test$variable_id[i], "-", test$datetime_start[i], "to", test$datetime_end[i], ".nc") # 功能1:文件存在校验,已存在则跳过 if (file.exists(destfile)) { message(paste("跳过已存在文件:", basename(destfile))) next } # 功能2:异常捕获,单个文件下载失败不中断整体任务 dl_status <- try({ download.file(url, destfile, mode = "wb") }, silent = FALSE) # 记录失败的文件信息 if (inherits(dl_status, "try-error")) { failed_list <- c(failed_list, list( url = url, destpath = destfile )) message(paste("下载失败,已跳过:", basename(destfile))) } } # 任务结束后输出失败汇总 if (length(failed_list) > 0) { message("\n=== 下载完成,以下文件下载失败,重新运行代码即可自动重试 ===") print(as.data.frame(do.call(rbind, failed_list))) } else { message("\n=== 所有文件下载完成 ===") }
实现逻辑说明
- 文件存在校验:调用R内置函数
file.exists()检测目标路径下的文件是否存在,存在时通过next指令直接进入下一轮循环,完全避免重复下载。代码保留了你原来的文件命名规则,和你已经下载完成的文件完全匹配,已下载文件的命名参考如下:
- 异常捕获:用
try()包裹下载操作,遇到连接超时、URL失效、网络中断等错误时不会终止整个循环,会自动跳过当前异常文件继续后续下载。 - 实用优化:
- 调整了R默认的下载超时阈值,适配大文件下载场景,可根据自身网络情况修改
timeout参数值 - 为
download.file()增加mode = "wb"参数,强制二进制写入,避免Windows环境下NetCDF文件下载后损坏 - 增加失败日志汇总,任务结束后会统一列出所有下载失败的文件,重新运行代码时会自动跳过已完成文件、重试失败文件,不需要手动修改代码。
- 调整了R默认的下载超时阈值,适配大文件下载场景,可根据自身网络情况修改
内容的提问来源于stack exchange,提问作者mikaeldp
相关产品推荐
相关产品推荐

