已实现单文件上传的Shiny应用传多文件至Google Drive时报错咨询
多文件上传至Google Drive的问题修复
报错根因
- 给
fileInput开启multiple = TRUE后,input$file返回的是对应多文件的数据框,其中datapath(Shiny生成的本地临时文件路径)、name(用户选择的原始文件名)都是长度为N的字符向量(N为选中的文件数) googledrive包的drive_upload()接口默认只支持单文件上传,要求传入的media、name参数必须是长度为1的字符串。直接把向量传给接口就会直接触发两类报错:- 内部文件存在性校验
if (!file.exists(media))时,因为输入是向量不是单值,R会只取第一个元素做判断,弹出长度大于1的警告 - 内部路径名校验逻辑检测到传入的
name是向量不是字符串,直接抛出rationalize_path_name: is_string(name) is not TRUE的错误
- 内部文件存在性校验
修复方案
核心逻辑为遍历上传的文件列表,逐个调用drive_upload完成上传,同时补充必要的容错处理:
- 预先定位目标Google Drive文件夹,避免动态路径解析失败
- 对单文件上传逻辑增加错误捕获,单个文件上传异常不中断整体流程
- 增加上传完成后的状态反馈
修复后可直接运行的示例代码:
library(googledrive) library(shiny) # 完成Google Drive账号授权(首次运行会弹出浏览器授权页面) drive_auth() ui <- fluidPage( fileInput(inputId = "file", label = "选择要上传的文件(可多选)", accept = NULL, multiple = TRUE), verbatimTextOutput("upload_status") ) server <- function(input, output) { # 预先获取目标文件夹的驱动器元数据,避免每次上传重复解析路径 target_folder <- drive_get(path = "my_folder") upload_result <- reactiveVal(NULL) observeEvent(input$file, { # 清空之前的上传状态 upload_result(NULL) # 遍历所有选中的文件逐个上传 upload_log <- apply(input$file, 1, function(file_row) { current_datapath <- file_row[["datapath"]] current_name <- file_row[["name"]] # 单文件上传容错捕获 tryCatch({ drive_upload( media = current_datapath, name = current_name, path = target_folder, overwrite = FALSE # 避免重名文件自动覆盖 ) paste0("✅ ", current_name, " 上传成功") }, error = function(e) { paste0("❌ ", current_name, " 上传失败:", e$message) }) }) upload_result(upload_log) }) output$upload_status <- renderPrint({ req(upload_result()) upload_result() }) } shinyApp(ui, server)
实操注意事项
- 首次运行代码时需要完成Google账号授权,授权信息会默认缓存在本地,后续运行无需重复授权
- 如果目标文件夹
my_folder不存在,需要先调用drive_mkdir("my_folder")创建,否则drive_get会抛出找不到路径的错误 - 生产环境部署时,可使用服务账号授权替代浏览器交互授权,避免Shiny服务器环境下的授权阻塞
内容的提问来源于stack exchange,提问作者Zach Margulies
相关产品推荐
相关产品推荐

