谢谢你们所有的帮助,因此在团队驱动器中设置这个递归循环。以下是我到目前为止的情况。我现在唯一的问题是我指定的Team Drive中有数万个文件夹。所以我认为我需要获得一个延续令牌来保持脚本运行超过6分钟。但是我完全不知道在脚本中获取或存储令牌的位置。我认为最简单的方法是每1-10次迭代运行一次令牌是安全的。以下是我目前的代码:
function generateFolderTree() {
try {
var rootFolder = DriveApp.getFolderById('xxxxxxxxxxxxxxx');
var rootFolderName = rootFolder.getName();
var rootsFolders = rootFolder.getFolders();
//var ss = SpreadsheetApp.create("Emptyfolderslist"+ Math.floor(Date.now() / 1000));
var ss = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxx');
var sheet = ss.getSheets()[0];
sheet.appendRow(["Parent Folder", "Folder URL", "Folder Name", "", "folder count", "file count"]);
while( rootsFolders.hasNext()) {
var currentFolder = rootsFolders.next()
var currentFolderFiles = currentFolder.getFiles();
var currentFolderFolders = currentFolder.getFolders();
var folderscount = 0;
var filescount = 0;
while( currentFolderFiles.hasNext()){
filescount ++;
currentFolderFiles.next();
}
while( currentFolderFolders.hasNext()){
folderscount++;
currentFolderFolders.next();
}
var path = '';
var parentfldrs = currentFolder.getParents();
while( parentfldrs.hasNext()) {
path = path + " - " + parentfldrs.next().getName();
}
sheet.appendRow(["'============================="]);
sheet.appendRow([path, currentFolder.getUrl(), currentFolder.getName(), "", folderscount, filescount]);
getChildFolders(currentFolder, ss);
}
} catch (e) {
Logger.log(e.toString());
}
}
function getChildFolders(aFolder, ss) {
var childFolders = aFolder.getFolders();
var filesInFolder = aFolder.getFiles();
var sheet = ss.getSheets()[0];
var foldercount = 0;
var filecount = 0;
var childFolder = '';
var parentFolders = '';
var loop = 0;
while( childFolders.hasNext()){
foldercount = 0;
filecount = 0;
childFolder = childFolders.next();
var subFolders = childFolder.getFolders();
var subFiles = childFolder.getFiles();
while( subFolders.hasNext()) {
foldercount++;
subFolders.next();
}
while( subFiles.hasNext()) {
filecount++;
subFiles.next()
}
var parentfldrs = childFolder.getParents();
while( parentfldrs.hasNext()) {
parentFolders = parentfldrs.next().getName();
}
sheet.appendRow([parentFolders, childFolder.getUrl(), "'----", childFolder.getName(), foldercount, filecount]);
getChildFolders(childFolder, ss);
}
}
我在这里阅读了其他几个使用搜索的类似问题的链接,如下所示:
Google Apps Script: How to use ContinuationToken with recursive folder iterator
Google Apps Script To Copy Entire Google Drive File Structure; How To Avoid Timeouts?
答案 0 :(得分:0)
在执行Google Apps脚本调用之间存储动态项目的唯一方法是使用PropertiesService或CacheService。 通常在执行之间不会更改的静态项(例如电子表格ID或对特定CacheService的引用)可以安全地存储为全局变量。
如果您计划在几分钟/小时内使用延续令牌,我建议CacheService
。如果您需要在超过6小时后保留延续令牌,则需要PropertiesService
(因为6小时是放入后在CacheService中保留的最长时间)。
您需要添加程序逻辑,以便从循环中的任意点恢复。如果您确保只输入将在剩余时间内完成的循环 - 即将开始时间存储在变量(var start = new Date().getTime()
)中,并检查在您之前剩余的时间,则从任意点恢复将更容易开始一个新的循环(if (new Date().getTime() - start < someMaxDuration) {...}
)。如果没有足够的时间(例如1m,30s等),那么你应该保存状态并退出。如果你不保存状态并干净地退出,你将重复数据,因为一些内部循环会重复。
最简单的开始是存储根级别迭代器的continuationToken
,如您对链接问题的回答所做的那样:Google Apps Script To Copy Entire Google Drive File Structure; How To Avoid Timeouts?:
...
while( rootFolders.hasNext() {
// If more than 2/3 the execution time has been used, bail out.
if( new Date().getTime() - start > 200 * 1000)
return;
...
getChildFolders(currentFolder, ss);
// Store the continuation token for the maximum time (6h).
if( rootFolders.hasNext())
cache.put("ROOT_CONTINUE_TOKEN", rootFolders.getContinuationToken(), 21600);
else
cache.remove("ROOT_CONTINUE_TOKEN");
}
...
要恢复,您首先要检查该密钥的缓存/属性,如果不存在,则从头开始。您可能需要在缓存/属性中存储其他值(并且类似地使用存储的值):
var cache = CacheService.getScriptCache();
function generateFolderTree() {
var cached = cache.get("someKey");
var folderIterator;
if(cached) {
folderIterator = DriveApp.continueFolderIterator(cached);
/* code for initializing a resumed iteration */
}
else {
/* code for initializing an iteration from scratch */
}
/* code for iterating */
}
答案 1 :(得分:0)
如果要使用现成的模板,则可以将其用于递归文件夹和暂停/继续功能。请查看my answer来回答类似的问题。
基本上,这是通过存储对象数组来完成的,以便我们知道在每个文件夹迭代器和文件迭代器中恢复的位置。