如何使用Google Drive Java API的v3版本复制Google Drive上的文件?

huangapple go评论63阅读模式
英文:

How do I copy a file on a Google Drive using v3 of the Google Drive Java API?

问题

I'm having trouble copying a file on a Google Drive using v3 of the Google Drive API for Java.

The file in question is on a shared team drive, and I'm reading in credentials that are associated with a service account. The service account has "manager" access to the drive in question.

Here is my code that is trying to copy the file. It's in Scala, rather than Java, but hopefully it will be clear enough anyway, even if you don't know Scala. (In case you don't already know, Scala is a programming language that targets the JVM and interoperates with Java in a relatively painless manner.)

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

[Erratum: As pointed out in the accepted solution provided by ziganotschka below, the only thing I needed to do to get things working right was to add .setSupportsAllDrives(true) before the .execute() above.]

Note that GFile is just an alias for com.google.api.services.drive.model.File. And ArchiveDriveService is a variable I defined to hold my Drive service object. TemplateFileId contains the ID of the Google Drive file that I want to copy.

This is the error that I get when I run this:

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

Despite the above error, ArchiveDriveService works fine for getting a list of files from the drive. E.g., this code works fine:

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})")
    }
}

If I run the above, I get the following output:

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)

You can see from the above listing, that one of the files listed is the file that I'm trying to copy. I.e., it has the fileId "1BjvZG6Ub7smBWrhC82aRD2LRUehB_U6AhmnXwrsuLks". And yet the error message I'm getting says that this file cannot be found.

This is how I'm making 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
}

Please help.

英文:

I'm having trouble copying a file on a Google Drive using v3 of the Google Drive API for Java.

The file in question is on a shared team drive, and I'm reading in credentials that are associated with a service account. The service account has "manager" access to the drive in question.

Here is my code that is trying to copy the file. It's in Scala, rather than Java, but hopefully it will be clear enough anyway, even if you don't know Scala. (In case you don't already know, Scala is a programming language that targets the JVM and interoperates with Java in a relatively painless manner.)

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

[Erratum: As pointed out in the accepted solution provided by ziganotschka below, the only thing I needed to do to get things working right was to add .setSupportsAllDrives(true) before the .execute() above.]

Note that GFile is just an alias for com.google.api.services.drive.model.File. And ArchiveDriveService is a variable I defined to hold my Drive service object. TemplateFileId contains the ID of the Google Drive file that I want to copy.

This is the error that I get when I run this:

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

Desipte the above error, ArchiveDriveService works fine for getting a list of files from the drive. E.g., this code works fine:

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

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

If I run the above, I get the following output:

     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)

You can see from the above listing, that one of the files listed is the file that I'm trying to copy. I.e., it has the fileId "1BjvZG6Ub7smBWrhC82aRD2LRUehB_U6AhmnXwrsuLks". And yet the error message I'm getting says that this file cannot be found.

This is how I'm making 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(&quot;user.home&quot;))
    val secrets = parent.resolve(&quot;.secrets&quot;)
    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
  }

Please help.

答案1

得分: 1

当你复制位于共享驱动器上的文件时,需要指定相同的设置以进行列表操作:

.setSupportsAllDrives(true)

请查看Files: copy参数

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

  • 请注意,默认情况下,文件将复制到与原始文件位于相同的(共享)文件夹/驱动器中。
  • 如果您想将其复制到其他位置,您需要指定parents[]参数。
英文:

When you copy a file that is located on a shared Drive, you need to specify the same like for listing it:

.setSupportsAllDrives(true)

See parameters of Files: copy:

> supportsAllDrives
>Whether the requesting application supports
> both My Drives and shared drives. (Default: false)

  • Mind that by default the file will be copied into the same (shared) folder / drive where the original file is located
  • If you want to copy it elsewhere, you nedd to specify the parents[] parameter

huangapple
  • 本文由 发表于 2020年7月23日 07:17:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/63044508.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定