首页 > 解决方案 > 如何使用 Google Drive Java API v3 复制 Google Drive 上的文件?

问题描述

我在使用 Java 版 Google Drive API v3 复制 Google Drive 上的文件时遇到问题。

有问题的文件位于共享团队驱动器上,我正在读取与服务帐户关联的凭据。服务帐户具有对相关驱动器的“管理员”访问权限。

这是我试图复制文件的代码。它在 Scala 中,而不是在 Java 中,但希望它无论如何都会足够清楚,即使您不了解 Scala。(如果您还不知道,Scala 是一种以 JVM 为目标并以相对轻松的方式与 Java 互操作的编程语言。)

    val fileCopy = new GFile()
    fileCopy.setName("Test Copy")
    try {
      ArchiveDriveService
        .files()
        .copy(TemplateFileId, fileCopy)
        .execute()
    } catch {
      case e: IOException =>
        fprint("An error occured: " + e)
    }

[勘误表:正如下面 ziganotschka 提供的公认解决方案中所指出的,我唯一需要做的就是.setSupportsAllDrives(true)在上述内容之前添加.execute()。]

请注意,这GFile只是com.google.api.services.drive.model.File. 并且ArchiveDriveService是我定义的一个变量来保存我的Drive服务对象。TemplateFileId包含我要复制的 Google Drive 文件的 ID。

这是我运行此程序时遇到的错误:

     {
       "code" : 404,
       "errors" : [ {
         "domain" : "global",
         "location" : "fileId",
         "locationType" : "parameter",
         "message" : "File not found: 1BjvZG6Ub7smBWrhC82aRD2LRUehB_U6AhmnXwrsuLks.",
         "Reason" : "notFound"
       } ],
       "message" : "File not found: 1BjvZG6Ub7smBWrhC82aRD2LRUehB_U6AhmnXwrsuLks."
     }

排除上述错误,ArchiveDriveService可以很好地从驱动器中获取文件列表。例如,这段代码工作正常:

    val result = ArchiveDriveService
      .files()
      .list()
      .setCorpora("drive")
      .setDriveId(driveId)
      .setFields("nextPageToken, files(id, name)")
      .setIncludeItemsFromAllDrives(true)
      .setPageSize(10)
      .setSpaces("drive")
      .setSupportsAllDrives(true)
      .execute()

    val files = result.getFiles()
    if (files == null || files.isEmpty()) {
        fprint("No files found.")
    } else {
        fprint("Files:")
        for (file <- files.asScala) {
          fprint(s"${file.getName} (${file.getId})")
        }
    }

如果我运行上面的,我得到以下输出:

     Files: 
     Copy of Template for Double Stranded (plasmid NGS, gDNA NGS) calculator (12_UODoLGbN04btC3dKh1yWV0yblGzMe0jEM-FWibVSM)
     Copy of Template for Double Stranded (plasmid NGS, gDNA NGS) calculator (1B0RUHZlakDLfH-12czZAzgABv3pGDhZXD-GIyeXgARA)
     Template for Double Stranded (plasmid NGS, gDNA NGS) calculator (1BjvZG6Ub7smBWrhC82aRD2LRUehB_U6AhmnXwrsuLks)
     Double Stranded Sheet (1MZAf4L0tPiqxW3yNG1oFigEkVjZB1G98)
     test (1zIayPNDWHNscbPdVYBICF001l-TbbZTl)
     foo (1tLlflOLg5OJ7w-YGRloWF-ShriRkrvTO4WV6-X9nl5A)
     foo.xlsx (1BF8--UOriadQSxF0kWMr9-Z0bRepcntI)
     Template for Double Stranded (plasmid NGS, gDNA NGS) calculator.xlsx (1qXAW1BCaFJDUxKd20LJB7haBmf4YCGkc)
     build.sbt (1OqG1iTc0fzcwbszc2-H-rhiq-3jNJpEw)

您可以从上面的清单中看到,列出的文件之一是我要复制的文件。即,它具有fileId“1BjvZG6Ub7smBWrhC82aRD2LRUehB_U6AhmnXwrsuLks”。然而,我收到的错误消息说找不到这个文件。

这就是我的制作方式ArchiveDriveService

  val ArchiveDriveService = newDriveService(ArchiveCredentialsFilename)

  def newDriveService(credentialsFilename: String): Drive = {
    new Drive.Builder(HttpTransport,
                      TheJsonFactory,
                      new HttpCredentialsAdapter(getCredentials(credentialsFilename)))
      .setApplicationName(ApplicationName)
      .build()
  }

  def getCredentials(credentialsFilename: String): GoogleCredentials = {
    val parent = Paths.get(System.getProperty("user.home"))
    val secrets = parent.resolve(".secrets")
    val credentialsPath = secrets.resolve(credentialsFilename)
    val in = new FileInputStream(credentialsPath.toFile)

    // This scope gives us full read/write access to the shared drive:
    val scopes = List(DriveScopes.DRIVE).asJava

    val credentials = GoogleCredentials.fromStream(in).createScoped(scopes)
    in.close()
    credentials
  }

请帮忙。

标签: javascalagoogle-drive-api

解决方案


当您复制位于共享云端硬盘上的文件时,您需要指定相同的内容来列出它:

.setSupportsAllDrives(true)

参数Files: copy:_

supportsAllDrives
请求应用程序是否支持“我的驱动器”和共享驱动器。(默认:假)

  • 请注意,默认情况下,文件将被复制到原始文件所在的相同(共享)文件夹/驱动器中
  • 如果你想把它复制到别处,你需要指定parents[]参数

推荐阅读