代码之家  ›  专栏  ›  技术社区  ›  Bill

谷歌应用程序脚本复制整个谷歌硬盘文件结构;如何避免超时?

  •  5
  • Bill  · 技术社区  · 10 年前

    我的组织正在转换为Google Business帐户,每个人都需要将自己的Drive文件转移到新帐户。驱动器不允许在这些帐户之间转移所有权,因此我创建了一个脚本,将文件和文件夹从旧帐户复制到新帐户。(旧帐户的内容已移动到与新帐户共享的文件夹中。)

    以下是我到目前为止的情况:

    function copyDrive() {
      var originFolder = DriveApp.getFolderById(originFolderID);
      var destination = DriveApp.getFolderById(destinationID);
      copyFiles(originFolder, destination);
    
    };
    
    function copyFiles(passedFolder, targetFolder) {
      var fileContents = passedFolder.getFiles();
      var file;
      var fileName;
    
      while(fileContents.hasNext()) {
        file = fileContents.next();
        fileName = file.getName();
        file.makeCopy(fileName, targetFolder);
      }
      copySubFolders(passedFolder, targetFolder);
    };
    
    function copySubFolders(passedFolder, targetFolder) {
      var folderContents = passedFolder.getFolders();
      var folder;
      var folderName;
    
      while(folderContents.hasNext()) {
        folder = folderContents.next();
        folderName = folder.getName();
        var subFolderCopy = targetFolder.createFolder(folderName);
        copyFiles(folder, subFolderCopy);
      }
    };
    

    请原谅任何不雅之处;我是这方面的新手。该脚本实际上工作得很好,并保留了文件夹结构,但在复制约150个文件和文件夹后超时。我一直在研究如何使用延续令牌 this post 密切关注。我认为我停留在概念层面上,因为我不确定延续标记将如何与我设置的递归函数交互。看来我最后会得到一堆 copySubFolders 函数,并且它们都需要自己的延续令牌。当然,它们的迭代器都使用相同的变量名,所以我真的不知道如何设置它。

    有什么想法吗?很抱歉发布了这样一个无助的新手问题;我希望这至少对某人来说是一个有趣的问题。

    3 回复  |  直到 8 年前
        1
  •  4
  •   Bill    10 年前

    我想我已经解决了概念问题,尽管我正在

    很抱歉,发生了服务器错误。请稍等,然后重试。(第9行,文件“代码”)

    当我尝试执行它时。

    基本上,我将其设置为一次只复制一个顶级文件夹,并且对于其中的每一个,它都使用我以前使用的递归函数。它应该为第一级文件夹和根文件夹中的任何文件保存延续令牌,以便在下一次执行中从它停止的地方恢复。这样,令牌就不会包含在递归函数堆栈中。

    function copyDrive() {
    
    
      var originFolder = DriveApp.getFolderById(originFolderID);
      var destination = DriveApp.getFolderById(destinationID);
    
      var scriptProperties = PropertiesService.getScriptProperties();
      var fileContinuationToken = scriptProperties.getProperty('FILE_CONTINUATION_TOKEN');
      var fileIterator = fileContinuationToken == null ?
        originFolder.getFiles() : DriveApp.continueFileIterator(fileContinuationToken);
      var folderContinuationToken = scriptProperties.getProperty('FOLDER_CONTINUATION_TOKEN');
      var folderIterator = folderContinuationToken == null ?
        originFolder.getFolders() : DriveApp.continueFolderIterator(folderContinuationToken);
    
      try {
        var rootFileName;
        while(fileIterator.hasNext()) {
          var rootFile = fileIterator.next();
          rootFileName = rootFile.getName();
          rootFile.makeCopy(rootFileName, destination);
          }
    
        var folder = folderIterator.next();
        var folderName = folder.getName();
        var folderCopy = folder.makeCopy(folderName, destination);
    
    
        copyFiles(folder, folderCopy);
    
      } catch(err) {
        Logger.log(err);
      }
    
      if(fileIterator.hasNext()) {
        scriptProperties.setProperty('FILE_CONTINUATION_TOKEN', fileIterator.getContinuationToken());
      } else {
        scriptProperties.deleteProperty('FILE_CONTINUATION_TOKEN');
      }
      if(folderIterator.hasNext()) {
        scriptProperties.setProperty('FOLDER_CONTINUATION_TOKEN', folderIterator.getContinuationToken());
      } else {
        scriptProperties.deleteProperty('FOLDER_CONTINUATION_TOKEN');
      }
    
    };
    
    function copyFiles(passedFolder, targetFolder) {
      var fileContents = passedFolder.getFiles();
      var file;
      var fileName;
    
      while(fileContents.hasNext()) {
        file = fileContents.next();
        fileName = file.getName();
        file.makeCopy(fileName, targetFolder);
      }
      copySubFolders(passedFolder, targetFolder);
    };
    
    function copySubFolders(passedFolder, targetFolder) {
      var subFolderContents = passedFolder.getFolders();
      var subFolder;
      var subFolderName;
    
      while(folderContents.hasNext()) {
        subFolder = subFolderContents.next();
        subFolderName = subFolder.getName();
        var subFolderCopy = targetFolder.createFolder(folderName);
        copyFiles(subFolder, subFolderCopy);
      }
    };
    
        2
  •  2
  •   GMGrimley    10 年前

    我知道你想要一种简单、编程的方式来实现这一点,但安装GoogleDriveforDesktop并右键单击、复制、粘贴可能是最简单的。

    想法:

    1. 创建一个文件夹,用户将其驱动器的每个项目都放在其中。(我看你已经这么做了。)
    2. 与新帐户共享该文件夹。(我看你也已经这么做了。)
    3. 使用Drive for Desktop登录他们的新帐户。
    4. 复制桌面驱动器中的文件夹并将其粘贴回。所有权将转移到新帐户。

    只是一个想法。

        3
  •  0
  •   Senseful    6 年前

    您需要存储一个文件夹迭代器和文件迭代器数组,因为每个文件夹都可能有一个嵌套的文件夹数组。如果您正在重复使用与公认的解决方案相同的文件夹迭代器,则无法继续使用更多的顶级文件夹。

    看看 my answer 这里有一个模板,您可以使用它递归地遍历内置恢复功能的驱动器中的所有文件。