Google Apps 脚本复制整个 Google 驱动器文件结构;如何避免超时?
Google Apps Script To Copy Entire Google Drive File Structure; How To Avoid Timeouts?
我的组织正在切换到 Google 企业帐户,每个人都需要将他们的云端硬盘文件转移到他们的新帐户。 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
函数,它们每个都需要自己的延续标记。当然他们的迭代器都使用相同的变量名,所以我真的不知道如何设置它。
有什么想法吗?很抱歉发布这样一个无助的新手问题;我希望这至少对某些人来说是一个有趣的问题。
我知道您想要一种简单的编程方式来执行此操作,但最简单的方法可能是安装 Google Drive for Desktop 并让它们右键单击、复制、粘贴。
想法:
- 创建一个文件夹,用户可以在其中放置其云端硬盘的所有项目。 (我看到你已经这样做了。)
- 与他们的新帐户共享该文件夹。 (我看到你也已经这样做了。)
- 使用 Drive for Desktop 登录他们的新帐户。
- 复制桌面版云端硬盘中的文件夹并将其粘贴回原处。所有权将转移到新帐户。
只是一个想法。
我想我已经解决了概念上的问题,尽管我得到了
We're sorry, a server error occurred. Please wait a bit and try again. (line 9, file "Code")
当我尝试执行它时。
基本上,我将其设置为一次仅尝试复制一个顶级文件夹,并且对于其中的每一个,它都使用我之前使用的递归函数。它应该为第一级文件夹和根文件夹中的任何文件保存继续令牌,以便它可以在下一次执行时从它停止的地方继续执行。这样,令牌就不会参与我的递归函数堆栈。
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);
}
};
您将需要存储一个文件夹迭代器和文件迭代器数组,因为每个文件夹都可以有一个嵌套的文件夹数组。如果您重复使用与接受的解决方案中相同的文件夹迭代器,您将无法在更多顶级文件夹上继续。
查看 my answer 此处的模板,您可以使用该模板递归迭代驱动器中的所有文件,并内置恢复功能。
我的组织正在切换到 Google 企业帐户,每个人都需要将他们的云端硬盘文件转移到他们的新帐户。 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
函数,它们每个都需要自己的延续标记。当然他们的迭代器都使用相同的变量名,所以我真的不知道如何设置它。
有什么想法吗?很抱歉发布这样一个无助的新手问题;我希望这至少对某些人来说是一个有趣的问题。
我知道您想要一种简单的编程方式来执行此操作,但最简单的方法可能是安装 Google Drive for Desktop 并让它们右键单击、复制、粘贴。
想法:
- 创建一个文件夹,用户可以在其中放置其云端硬盘的所有项目。 (我看到你已经这样做了。)
- 与他们的新帐户共享该文件夹。 (我看到你也已经这样做了。)
- 使用 Drive for Desktop 登录他们的新帐户。
- 复制桌面版云端硬盘中的文件夹并将其粘贴回原处。所有权将转移到新帐户。
只是一个想法。
我想我已经解决了概念上的问题,尽管我得到了
We're sorry, a server error occurred. Please wait a bit and try again. (line 9, file "Code")
当我尝试执行它时。
基本上,我将其设置为一次仅尝试复制一个顶级文件夹,并且对于其中的每一个,它都使用我之前使用的递归函数。它应该为第一级文件夹和根文件夹中的任何文件保存继续令牌,以便它可以在下一次执行时从它停止的地方继续执行。这样,令牌就不会参与我的递归函数堆栈。
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);
}
};
您将需要存储一个文件夹迭代器和文件迭代器数组,因为每个文件夹都可以有一个嵌套的文件夹数组。如果您重复使用与接受的解决方案中相同的文件夹迭代器,您将无法在更多顶级文件夹上继续。
查看 my answer 此处的模板,您可以使用该模板递归迭代驱动器中的所有文件,并内置恢复功能。