首页 > 解决方案 > 如何查找 Google Drive 文件的父文件夹的整个层次结构?

问题描述

我可以使用 Google Drive API 来做到这一点:

drive.files.get(
  {
    fields: "parents",
    fileId: "######"
  },
  (err, results) => {
    ...
  }
);

但是,我只能获取文件夹的 ID,比文件高一级。

如何获取包含 Google Drive 文件的父文件夹、包含该文件夹的文件夹、包含该文件夹的文件夹等的整个层次结构?

标签: javascriptnode.jsgoogle-drive-api

解决方案


这个方法怎么样?我认为您的情况有几种解决方案。因此,请将此视为其中之一。不幸的是,无法使用files.getDrive API 检索所有文件夹,包括文件夹中的子文件夹。并且当q用于files.listDrive API 时,'folder ID' in parents仅检索文件夹 ID 中的文件夹。无法检索文件夹 ID 中子文件夹下的文件夹。所以在这个方法中,我使用了以下流程。

  1. 检索 Google Drive 中的所有文件夹。
    • 在此示例脚本中,如果您的 Google Drive 中的文件夹数量少于 1000 个,则通过一次 API 调用检索所有文件夹。如果文件夹数量从 1000 到 2000,则使用 2 个 API 调用。
  2. 使用所有文件夹的列表创建文件夹树。

示例脚本:

function run(auth) {
    var drive = google.drive({version: 'v3', auth: auth});
    getFolderTree(drive, "", []);
}

function getFolderTree(drive, nextPageToken, folderList) {
    drive.files.list({
        pageToken: nextPageToken ? nextPageToken : "",
        pageSize: 1000,
        q: "mimeType='application/vnd.google-apps.folder'",
        fields: "files(id,parents),nextPageToken",
    }, (err, {data}) => {
        if (err) return console.log('The API returned an error: ' + err);
        const token = data.nextPageToken;
        Array.prototype.push.apply(folderList, data.files);
        if (token) {
            getFolderTree(drive, token, folderList);
        } else {

            // This script retrieves all folders including subfolders under this folder ID.
            const folderId = "### Top folder ID ###";

            const folderTree = function c(folder, folderSt, res) {
                let ar = folderList.filter(e => e.parents[0] == folder);
                folderSt += folder + "#_aabbccddee_#";
                let arrayFolderSt = folderSt.split("#_aabbccddee_#");
                arrayFolderSt.pop();
                res.push(arrayFolderSt);
                ar.length == 0 && (folderSt = "");
                ar.forEach(e => c(e.id, folderSt, res));
                return res;
            }(folderId, "", []);

            // Output the folder tree.
            console.log(folderTree);
        }
    });
}

输出 :

当文件夹结构如下。(您可以在此示例脚本中设置顶级文件夹 ID。)

在此处输入图像描述

该脚本如下创建一个数组。

[
  ['topFolderId'],
  ['topFolderId','folderId_2a'],
  ['topFolderId','folderId_2b'],
  ['topFolderId','folderId_2b','folderId_3a'],
  ['topFolderId','folderId_2b','folderId_3b']
]

笔记 :

  • 我确认这个示例脚本在 googleapis 上使用 v30.0.0 工作。
  • 通常,文件夹树是通过按顺序从顶层文件夹中检索文件夹来创建的。但是当Drive API用于这种情况时,如果顶层文件夹中有很多文件夹,则需要调用很多API。因此,在这种方法中,我尝试使用所有文件夹的列表创建具有少量 API 调用的文件夹树。
  • 这是一个简单的示例脚本,因此请根据您的环境对其进行修改。

参考 :

编辑 :

此更新后的脚本检索整个文件夹树,包括输入的 folderId。对于上面的脚本,run()getFolderTree()进行了修改。

function run(auth) {
    var drive = google.drive({version: 'v3', auth: auth});
    drive.files.get({fileId: "root", fields: "id"}, (err, {data}) => {
      getFolderTree(drive, "", [], data.id);
    });
}

function getFolderTree(drive, nextPageToken, folderList, rootId) {
    drive.files.list({
        pageToken: nextPageToken ? nextPageToken : "",
        pageSize: 1000,
        q: "mimeType='application/vnd.google-apps.folder'",
        fields: "files(id,name,parents),nextPageToken",
    }, (err, {data}) => {
        if (err) return console.log('The API returned an error: ' + err);
        const token = data.nextPageToken;
        Array.prototype.push.apply(folderList, data.files);
        if (token) {
            getFolderTree(drive, token, folderList, rootId);
        } else {

            // Please input folder ID.
            const inputId = "### Folder ID ###";

            const folderId = rootId;
            const folderTree = function c(folder, folderSt, res) {
                let ar = folderList.filter(e => e.parents[0] == folder);
                folderSt += folder + "#_aabbccddee_#";
                let arrayFolderSt = folderSt.split("#_aabbccddee_#");
                arrayFolderSt.pop();
                res.push(arrayFolderSt);
                ar.length == 0 && (folderSt = "");
                ar.forEach(e => c(e.id, folderSt, res));
                return res;
            }(folderId, "", []);
            let result = folderTree.filter(e => ~e.indexOf(inputId));
            if (result.length > 2) result.shift();

            // Output result.
            console.log(result);
        }
    });
}

对于上述情况,当folderId_2b输入 时inputId,可以检索到以下结果。

[
    ["topFolderId","folderId_2b","folderId_3a"],
    ["topFolderId","folderId_2b","folderId_3b"]
]

推荐阅读