R使用download.file从URL下载文件不指定文件名及压缩包损坏问题
压缩包损坏问题修复
你遇到的压缩包损坏问题与手动指定文件名无关,根因为非Unix系统下download.file默认使用文本模式传输文件,二进制格式的压缩包在文本模式下会被篡改编码导致损坏,只需增加mode = "wb"参数指定二进制传输即可解决,修正后代码如下:
url <- 'https://www.eea.europa.eu/data-and-maps/data/eea-reference-grids-2/gis-files/denmark-shapefile/at_download/file' # 指定二进制传输模式避免文件损坏 download.file(url, destfile ='Denmark_shapefile.zip', mode = "wb") unzip(zipfile = 'Denmark_shapefile.zip', exdir = '.')
问题1:为什么使用download.file函数时必须指定文件名?
- 这是R基础下载函数的安全设计,要求用户明确指定写入目标,避免歧义问题:部分下载链接无直接的文件名标识、或存在多级重定向,R无法确保自动识别的文件名合法、也无法判定是否会覆盖本地已有重名文件,因此要求用户主动指定
destfile参数保证写入行为符合预期。 - 原生
download.file没有内置自动文件名解析逻辑,因此该参数为必填项。
问题2:能否仅指定URL和存储文件夹,让下载的文件自动沿用服务端的原始命名?
可以实现,需要先从HTTP响应头的Content-Disposition字段提取服务端指定的原始文件名,再传入下载参数即可,示例实现如下:
library(htTR) url <- 'https://www.eea.europa.eu/data-and-maps/data/eea-reference-grids-2/gis-files/denmark-shapefile/at_download/file' save_dir <- "./" # 自定义存储文件夹路径 # 获取响应头提取原始文件名 resp_head <- HEAD(url) content_disposition <- headers(resp_head)$`content-disposition` origin_filename <- regmatches(content_disposition, regexpr('filename="(.+?)"', content_disposition, perl = TRUE))[[1]][2] full_save_path <- file.path(save_dir, origin_filename) # 自动使用原始文件名下载 GET(url, write_disk(full_save_path, overwrite = TRUE)) # 解压验证 unzip(full_save_path, exdir = save_dir)
- 上述逻辑无需手动指定文件名,仅需配置存储文件夹即可自动沿用服务端原始命名下载文件。
- 如果不希望引入第三方依赖,也可以自行调用系统curl命令解析响应头提取文件名,再传入原生
download.file的destfile参数实现同样效果。
内容的提问来源于stack exchange,提问作者Blaiso
相关产品推荐
相关产品推荐

