Shiny中用shinyFiles上传文件至GoogleDrive遇问题求助
解决Shiny+shinyFiles上传文件到GoogleDrive的“文件未找到”问题
我仔细看了你的代码,发现问题出在几个容易忽略的细节上,不是googledrive库的运行异常,咱们一步步来修正:
核心问题分析
- 变量作用域不一致:你在第一个
observe块里重新定义了volumes,但第二个observeEvent里调用的是server函数开头的初始volumes(仅getVolumes()),这会导致parseFilePaths解析用户选择的文件路径时出错,自然找不到文件。 - 多文件上传未做循环处理:当用户多选文件时,
as.character(file_selected$datapath)会变成一个路径向量,但drive_upload默认一次只能处理单个文件,直接传向量会触发错误。 - 未做空值检查:如果用户还没选文件就点击上传按钮,会直接报错,缺乏容错处理。
修正后的完整代码
library(shiny) library(shinyFiles) library(googledrive) # 提前完成GoogleDrive授权(首次运行会弹出授权页面) drive_auth() ui <- fluidPage( shinyFilesButton("file", "File select", "Please select a file", multiple = TRUE), verbatimTextOutput("txt_file"), actionButton("go","Upload to GoogleDrive"), # 新增提示输出,显示上传状态 verbatimTextOutput("upload_status") ) server <- function(input,output,session){ # 统一定义volumes,确保所有observe块都使用同一个配置 volumes <- reactive({ c(Home = fs::path_home(), "R Installation" = R.home(), getVolumes()()) }) observe({ shinyFileChoose(input, "file", roots = volumes(), session = session) if(!is.null(input$file)){ file_selected <- parseFilePaths(volumes(), input$file) output$txt_file <- renderPrint(file_selected) } }) observeEvent(input$go, { output$upload_status <- renderPrint("开始上传...") # 先检查是否有选中文件 if(is.null(input$file)){ output$upload_status <- renderPrint("请先选择要上传的文件!") return() } file_selected <- parseFilePaths(volumes(), input$file) # 循环处理每个选中的文件 upload_results <- lapply(seq(nrow(file_selected)), function(i){ file_path <- as.character(file_selected$datapath[i]) file_name <- as.character(file_selected$name[i]) # 用tryCatch捕获上传错误,方便排查问题 tryCatch({ drive_upload(media = file_path, name = file_name) paste0("成功上传:", file_name) }, error = function(e){ paste0("上传失败(", file_name, "):", e$message) }) }) # 输出上传结果 output$upload_status <- renderPrint(unlist(upload_results)) session$sendCustomMessage(type = 'testmessage', message = '上传操作完成') }) } shinyApp(ui = ui, server = server)
关键改动说明
- 统一volumes定义:用
reactive包裹volumes配置,确保所有用到的地方都调用同一个volumes(),避免路径解析不一致。 - 增加空值检查:点击上传按钮前先判断是否有选中文件,避免空值报错。
- 循环处理多文件:用
lapply遍历每个选中的文件,逐个调用drive_upload,同时保留原文件名。 - 错误捕获与状态提示:新增
upload_status输出,显示每个文件的上传结果,方便排查问题。 - 提前授权:在代码开头加入
drive_auth(),确保运行前完成GoogleDrive的授权(首次运行会弹出浏览器授权页面,按提示操作即可)。
测试步骤
- 运行修正后的代码,完成GoogleDrive授权。
- 点击"File select"按钮选择一个或多个文件,页面会显示选中文件的路径信息。
- 点击"Upload to GoogleDrive"按钮,等待上传完成,查看
upload_status的结果提示。
内容的提问来源于stack exchange,提问作者user8472609
相关产品推荐
相关产品推荐

