这是一个常见问题.
情景是: -
folderA____ folderA1____folderA1a \____folderA2____folderA2a \___folderA2b
...问题是如何列出根目录下所有文件夹中的所有文件folderA
.
首先要了解的是,在Google云端硬盘中,文件夹不是文件夹!
我们都习惯于Windows/nix等文件夹(aka目录)的概念.在现实世界中,文件夹是放置文档的容器.也可以将较小的文件夹放在较大的文件夹中.因此,可以将大文件夹视为包含其较小子文件夹内的所有文档.
但是,在Google云端硬盘中,文件夹不是容器,因此在Google云端硬盘的第一个版本中,它们甚至不称为文件夹,它们被称为收藏集.文件夹只是一个文件,其中包含(a)无内容,(b)特殊的mime类型(application/vnd.google-apps.folder).文件夹的使用方式正是如此与使用标签(也就是标签)的方式相同.理解这一点的最好方法是考虑GMail.如果查看打开的邮件项目的顶部,则会看到两个图标.带有工具提示"移动到"的文件夹和带有工具提示"标签"的标签.单击其中任何一个,将出现相同的对话框,所有这些都与标签有关.您的标签在左侧列出,在树状显示中看起来很像文件夹.重要的是,邮件项目可以有多个标签,或者您可以说,邮件项目可以位于多个文件夹中.Google Drive的文件夹与GMail标签的工作方式完全相同.
确定文件夹只是一个标签,没有什么可以阻止您在类似于文件夹树的层次结构中组织标签,实际上这是最常见的方式.
现在应该清楚的是,folderA2b中的文件(我们称之为MyFile)不是folderA的子项或孙项.它只是一个带有"folderA2b"标签(混淆地称为父)的文件.
好的,那么如何将所有文件"置于"文件夹A下?
替代方案1.递归
诱惑就是列出folderA的子项,对于任何文件夹的子项,递归列出他们的孩子,冲洗,重复.在极少数情况下,这可能是最好的方法,但对大多数情况来说,它有以下问题: -
为每个子文件夹执行服务器往返是非常耗时的.这当然取决于树的大小,所以如果你可以保证树的大小很小,那就可以了.
备选方案2.共同的父母
如果您的应用程序正在创建所有文件(即您正在使用drive.file范围),则此方法效果最佳.除了上面的文件夹层次结构,还要创建一个名为"MyAppCommonParent"的虚拟父文件夹.当您将每个文件创建为其特定文件夹的子文件时,您还将其设为MyAppCommonParent的子文件.如果您记得将文件夹视为标签,这将变得更加直观.您现在可以通过简单查询轻松检索所有descdesndants MyAppCommonParent in parents
.
备选方案3.文件夹优先
首先获取所有文件夹.是的,所有这些.将它们全部存储在内存中后,您可以爬行其父属性并构建树结构和文件夹ID列表.然后你可以做一个files.list?q='folderA' in parents or 'folderA1' in parents or 'folderA1a' in parents...
.使用这种技术,您可以在两个http调用中获取所有内容.
选项3的伪代码有点像......
// get all folders from Drive
files.list?q=mimetype=application/vnd.google-apps.folder and trashed=false&fields=parents,name
// store in a Map, keyed by ID
// find the entry for folderA and note the ID
// find any entries where the ID is in the parents, note their IDs
// for each such entry, repeat recursively
// use all of the IDs noted above to construct a ...
// files.list?q='folderA-ID' in parents or 'folderA1-ID' in parents or 'folderA1a-ID' in parents...
备选方案2是最有效的,但只有在您控制文件创建时才有效.备选方案3通常比备选方案1更有效,但可能存在某些小树大小,其中1是最佳的.