2014-03-12 77 views
7

我寫了一個腳本,可以通過在谷歌雲端硬盤文件夾有大量的文件進行迭代。由於我對這些文件所做的處理超出了最大執行時間。當然,我寫入腳本使用DriveApp.continueFileIterator(continuationToken):令牌存儲在項目屬性中,當腳本運行時,它會檢查是否有令牌,如果存在則從令牌創建FileIterator,如果不是則重新開始。正確使用

我發現了什麼是即使腳本與它仍然具有迭代的開頭開始延續標記重新啓動,再次嘗試處理相同的文件,這是浪費時間的後續執行。我是否錯過了一些至關重要的命令或方法,使它從離開的地方開始?我是否應該在while(content.hasNext())循環中的各個階段更新延續令牌?

這裏的瘦身,給你一個想法的示例代碼:

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

第一次執行或完成時是否超時? – Jonathon

回答

1

您的日期比較不會在你的方式工作。

var currentExecution = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd HH:mm:ss"); 

將存儲"2014-04-18 08:32:01",而文件日期file.getDateCreated()會返回一個Date對象比較這些使用任<>將始終返回false。

所以我建議你保存時間時間戳(因爲你不能店Date對象),然後比較,爲文件創建日期的時間戳。

// stored time stamp 
var lastExecution = scriptProperties.getProperty('LAST_EXECUTION'); 

… 

dateCreated = file.getDateCreated().getTime(); 

… 

var currentExecution = new Date().getTime(); 
scriptProperties.setProperty('LAST_EXECUTION',currentExecution); 

該比較將按照您的預期工作。

12

像喬納森說,你錯比較日期。但這不是你劇本的主要問題,也不是你所問的。

你得到錯誤的主要概念是,你做你的循環之前延續令牌不能保存。當你得到令牌時,它會保存那個時候的位置,如果你繼續迭代,那麼這個不會被保存,你將在後面重復這些步驟,就像你正在經歷的那樣。

獲得令牌後,你不能讓你的腳本發生錯誤終止。您必須測量您可以在5分鐘內處理多少個文件並在此之前手動停止腳本,以便您有機會保存令牌。

這裏做的正確方法:

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。您可能需要將這些文件存儲在驅動器文件中,因爲對於太多的ID,PropertiesService可能太小。