You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny中用shinyFiles上传文件至GoogleDrive遇问题求助

解决Shiny+shinyFiles上传文件到GoogleDrive的“文件未找到”问题

我仔细看了你的代码,发现问题出在几个容易忽略的细节上,不是googledrive库的运行异常,咱们一步步来修正:

核心问题分析

  1. 变量作用域不一致:你在第一个observe块里重新定义了volumes,但第二个observeEvent里调用的是server函数开头的初始volumes(仅getVolumes()),这会导致parseFilePaths解析用户选择的文件路径时出错,自然找不到文件。
  2. 多文件上传未做循环处理:当用户多选文件时,as.character(file_selected$datapath)会变成一个路径向量,但drive_upload默认一次只能处理单个文件,直接传向量会触发错误。
  3. 未做空值检查:如果用户还没选文件就点击上传按钮,会直接报错,缺乏容错处理。

修正后的完整代码

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的授权(首次运行会弹出浏览器授权页面,按提示操作即可)。

测试步骤

  1. 运行修正后的代码,完成GoogleDrive授权。
  2. 点击"File select"按钮选择一个或多个文件,页面会显示选中文件的路径信息。
  3. 点击"Upload to GoogleDrive"按钮,等待上传完成,查看upload_status的结果提示。

内容的提问来源于stack exchange,提问作者user8472609

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 20:22:31