文件夹迭代器连续令牌递归循环 [英] Folder Iterator Continuation Token Recursive Loop

查看:38
本文介绍了文件夹迭代器连续令牌递归循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谢谢你们到目前为止在Team Drive中设置此递归循环的所有帮助.以下是我到目前为止的内容.我目前唯一的问题是指定的Team Drive中有成千上万个文件夹.因此,我认为我需要获取一个延续令牌,以使脚本运行超过6分钟.但是我绝对不知道脚本在哪里获取或存储令牌.我认为最简单的方法是每1-10次迭代就运行一次令牌,以确保安全.下面是我当前的代码:

Thank you guys for all your help thusfar with setting up this recursive loop in Team drive. Below is what I have so far. My only problem at this point is that there are tens of thousands of folders in my specified Team Drive. So I think I need to get a continuation token to keep the script running longer than 6 minutes. However I have absolutely no clue where in the script to get or store the tokens. I think the easiest would be to just run the token every 1-10 iterations to be safe. Below is my current code:

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

我在这里还阅读了其他两个链接,这些链接使用搜索出现了类似的问题,如下所示:

I have read a couple other links here with similar questions using search, shown below:

Google Apps脚本:如何使用带有递归文件夹迭代器的ContinuationToken

Google用于复制整个Google云端硬盘文件结构的Apps脚本;如何避免超时?

推荐答案

在对Google Apps脚本的执行调用之间存储动态项目的唯一方法是使用

The only way to store dynamic items between execution calls to Google Apps Script is to use either the PropertiesService or CacheService. Static items which generally do not change between executions (such as a spreadsheet id or a reference to a particular CacheService) can safely be stored as global variables.

如果您打算在几分钟/小时内使用延续令牌,则建议使用 CacheService .如果您需要保留延续令牌以在6个小时后使用,则需要 PropertiesService (因为6个小时是某些东西在放入后将保留在CacheService中的最长时间).

If you plan to use the continuation token within a few minutes / hours, I would recommend CacheService. If you need to keep the continuation token for use after more than 6 hours, PropertiesService is required (as 6 hours is the max time something will stay in CacheService after being put in).

您将需要添加程序逻辑,以使您可以从循环中的任意点继续执行操作.如果您确保只输入将在剩余时间内完成的循环,则从任意点恢复将更容易-将开始时间存储在变量中( var start = new Date().getTime()),并检查剩余的时间,然后再开始新的循环( if(new Date().getTime()-start< someMaxDuration){...} ).如果没有足够的时间(例如1m,30s等),则应保存状态并退出.如果您不保存状态并干净地退出,则复制数据,因为某些内部循环将重复发生.

You will need to add program logic that enables resuming from an arbitrary point in your loops. Resuming from an arbitrary point will be easier to do if you ensure you only enter loops that will complete in the time remaining - i.e. store the start time in a variable (var start = new Date().getTime()), and check how much time is remaining before you start a new loop (if (new Date().getTime() - start < someMaxDuration) {...}). If there is insufficient time (say 1m, 30s, etc), then you should save state and exit. If you do not save state and exit cleanly, you will duplicate data, as some inner loops will get repeated.

最简单的开始是为根级迭代器存储 continuationToken ,如对链接的问题的回答所示:

The simplest place to start is storing the continuationToken for the root level iterator, as done in the answer to your linked question: 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");
}
...

要恢复,请先检查该键的缓存/属性,如果不存在,请从头开始.您可能需要在缓存/属性中存储其他值(并类似地使用存储的值):

To resume, you'd check cache/properties for that key first, and if not present, start from the beginning. You might need to store additional values in Cache/Properties (and similarly use the stored values):

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 */
}

这篇关于文件夹迭代器连续令牌递归循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆