gpt4 book ai didi

google-apps-script - DriveApp.continueFileIterator(continuationToken) 的正确用法

转载 作者:行者123 更新时间:2023-12-02 01:31:29 33 4
gpt4 key购买 nike

我编写了一个脚本来迭代 Google 云端硬盘文件夹中的大量文件。由于我对这些文件进行的处理,它超出了最大执行时间。当然,我写入脚本以使用 DriveApp.continueFileIterator(continuationToken): token 存储在项目属性中,当脚本运行时,它会检查是否有 token ,如果有,则从 token 创建 FileIterator 如果没有重新开始。

我发现,即使脚本使用继续标记重新启动,它仍然从迭代的开头开始,尝试再次处理相同的文件,这会浪费后续执行的时间。我是否错过了一些重要的东西,例如命令或方法,使其从停止的地方开始?我是否应该在 while(contents.hasNext()) 循环的各个阶段更新延续 token ?

这里是精简后的示例代码,可以为您提供一个想法:

function listFilesInFolder() {
var id= '0fOlDeRiDg';
var scriptProperties = PropertiesService.getScriptProperties();
var continuationToken = scriptProperties.getProperty('IMPORT_ALL_FILES_CONTINUATION_TOKEN');
var lastExecution = scriptProperties.getProperty('LAST_EXECUTION');
if (continuationToken == null) {
// first time execution, get all files from drive folder
var folder = DriveApp.getFolderById(id);
var contents = folder.getFiles();
// get the token and store it in a project property
var continuationToken = contents.getContinuationToken();
scriptProperties.setProperty('IMPORT_ALL_FILES_CONTINUATION_TOKEN', continuationToken);
} else {
// we continue to import from where we left
var contents = DriveApp.continueFileIterator(continuationToken);
}
var file;
var fileID;
var name;
var dateCreated;

while(contents.hasNext()) {
file = contents.next();
fileID = file.getId();
name = file.getName();
dateCreated = file.getDateCreated();
if(dateCreated > lastExecution) {
processFiles(fileID);
}
}
// Finished processing files so delete continuation token
scriptProperties.deleteProperty('IMPORT_ALL_FILES_CONTINUATION_TOKEN');
var currentExecution = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd HH:mm:ss");
scriptProperties.setProperty('LAST_EXECUTION',currentExecution);
};

最佳答案

就像乔纳森所说,你比较日期是错误的。但这不是您的脚本的主要问题,也不是您所要求的问题。

您错误的主要概念是在执行循环之前无法保存继续 token 。当您获得 token 时,它会保存您当时所在的位置,如果您之后继续迭代,则不会保存,您稍后将重复这些步骤,就像您正在经历的那样。

要稍后获取 token ,您不能让脚本因错误而终止。您必须测量 5 分钟内可以处理多少文件,并在此之前手动停止脚本,以便有机会保存 token 。

正确的做法是:

function listFilesInFolder() {
var MAX_FILES = 20; //use a safe value, don't be greedy
var id = 'folder-id';
var scriptProperties = PropertiesService.getScriptProperties();
var lastExecution = scriptProperties.getProperty('LAST_EXECUTION');
if( lastExecution === null )
lastExecution = '';

var continuationToken = scriptProperties.getProperty('IMPORT_ALL_FILES_CONTINUATION_TOKEN');
var iterator = continuationToken == null ?
DriveApp.getFolderById(id).getFiles() : DriveApp.continueFileIterator(continuationToken);


try {
for( var i = 0; i < MAX_FILES && iterator.hasNext(); ++i ) {
var file = iterator.next();
var dateCreated = formatDate(file.getDateCreated());
if(dateCreated > lastExecution)
processFile(file);
}
} catch(err) {
Logger.log(err);
}

if( iterator.hasNext() ) {
scriptProperties.setProperty('IMPORT_ALL_FILES_CONTINUATION_TOKEN', iterator.getContinuationToken());
} else { // Finished processing files so delete continuation token
scriptProperties.deleteProperty('IMPORT_ALL_FILES_CONTINUATION_TOKEN');
scriptProperties.setProperty('LAST_EXECUTION', formatDate(new Date()));
}
}

function formatDate(date) { return Utilities.formatDate(date, "GMT", "yyyy-MM-dd HH:mm:ss"); }

function processFile(file) {
var id = file.getId();
var name = file.getName();
//your processing...
Logger.log(name);
}

无论如何,有可能在运行之间创建了一个文件,而您在继续迭代时没有获得它。然后,通过在上次运行后保存执行时间,您也可能会在下次运行时错过它。我不知道您的用例,是否可以接受最终重新处理一些文件或错过一些文件。如果您根本无法遇到这两种情况,那么我看到的唯一解决方案是保存已处理的所有文件的 ID。您可能需要将它们存储在驱动器文件中,因为 PropertiesService 对于太多 id 来说可能太小。

关于google-apps-script - DriveApp.continueFileIterator(continuationToken) 的正确用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22365681/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com