如何检查SFTP服务器文件是否存在?httr/httr2报错排查与curl实现
检查SFTP服务器指定文件存在性的问题
我需要检查SFTP服务器上是否存在指定文件,尝试使用httr和httr2包实现但均失败,具体尝试代码及报错如下:
my_file_url <- "sftp://my_server/my_file.txt"
使用httr包的尝试
httr::HEAD(my_file_url, httr::authenticate(my_username, my_password))
报错信息:
Error in x$headers$`content-type` : $ operator is invalid for atomic vectors
使用httr2包的尝试
request(my_file_url) %>% req_method("HEAD") %>% req_auth_basic( my_username, my_password) %>% req_perform()
报错信息(已确认凭据正确):
Error: ! Authentication failure
我的疑问:
- 这两种尝试分别存在什么问题?
- 如何直接通过curl包实现文件存在性检查?
补充:我尝试过curl::curl_fetch_memory(my_file_url, handle = my_curl_handle),但该方法会下载文件,不符合需求。
问题解答
1. httr和httr2尝试失败的原因
httr包的问题
httr的HEAD方法是为HTTP/HTTPS协议设计的,对SFTP协议的支持不完善。请求SFTP资源时,返回的响应结构不符合httr预期的HTTP响应格式,导致它尝试访问不存在的x$headers$content-type元素,最终抛出原子向量无法使用$操作符的错误。
httr2包的问题
httr2同样默认针对HTTP/HTTPS优化,SFTP基于SSH认证体系,和HTTP Basic Auth逻辑完全不同。req_auth_basic是为HTTP Basic Auth设计的认证方式,无法适配SFTP的认证流程,因此即便凭据正确也会触发认证失败报错。
2. 使用curl包实现SFTP文件存在性检查
可以利用curl的CURLOPT_NOBODY选项,仅获取文件元信息而不下载内容,以此判断文件是否存在,代码如下:
library(curl) # 创建curl句柄并配置参数 h <- new_handle() handle_setopt(h, username = my_username, password = my_password, nobody = TRUE) # 仅请求文件元数据,不下载内容 # 发送请求并捕获结果 res <- tryCatch({ curl_fetch_memory(my_file_url, handle = h) }, error = function(e) { e }) # 判断文件状态 if (inherits(res, "error")) { if (grepl("Couldn't open file", res$message)) { cat("文件不存在\n") } else { cat("连接或认证错误:", res$message, "\n") } } else { if (res$status_code == 200) { cat("文件存在\n") } else { cat("文件不存在或访问受限,状态码:", res$status_code, "\n") } }
代码说明
nobody = TRUE:强制curl只获取文件的元数据(如大小、修改时间),不会下载文件主体内容,满足不下载文件的需求。- 通过
tryCatch捕获异常:文件不存在时curl会抛出包含"Couldn't open file"的错误,可直接据此判断;其他错误则对应连接或认证问题。 - 状态码判断:正常获取到元数据时,curl返回状态码200,说明文件存在;非200状态码则表示文件不存在或无访问权限。
内容的提问来源于stack exchange,提问作者Lefkios Paikousis
相关产品推荐
相关产品推荐

