You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Drive批量恢复文件版本遇脚本超时,求断点续传方案

Google Apps Script 断点续传实现方案

核心思路

  • 用Google脚本自带的**脚本属性(ScriptProperties)**存储执行进度,比如已处理的文件夹ID、文件ID列表、当前处理位置;文件量极大时,也可以在Drive根目录建个隐藏JSON文件存进度
  • 脚本启动先读进度,有断点就从断点续跑,没断点就从根目录开始
  • 主动监控运行时间,接近28分钟(留2分钟余量)时保存进度并终止,下次启动自动续传

具体实现步骤

1. 进度存储与读取

脚本启动时先检查有没有保存的进度:

  • 读ScriptProperties里的lastProcessedFolderId(最后处理的文件夹ID)、processedFileIds(已处理文件ID列表)、currentFileIndex(当前处理到的文件索引)
  • 没进度就从根文件夹开始;有进度就从指定位置继续

2. 处理过程中实时更新进度

  • 每处理完一个文件就更新进度到ScriptProperties,批量处理时也可以每20个文件存一次,避免频繁写入拖慢速度
  • 递归遍历文件夹时,同步记录当前所在的文件夹ID,确保断点能精准回到对应目录

3. 超时检测与主动终止

在循环里加运行时间判断:

  • 记录脚本启动时间startTime
  • 每次循环算已运行时长,到28分钟就保存进度并终止,留足时间完成进度写入

代码示例

function batchRestoreFiles() {
  // 读取断点进度
  const props = PropertiesService.getScriptProperties();
  const lastFolderId = props.getProperty('lastProcessedFolderId');
  const processedFiles = props.getProperty('processedFileIds') ? JSON.parse(props.getProperty('processedFileIds')) : [];
  const currentIndex = parseInt(props.getProperty('currentFileIndex')) || 0;
  const attackDate = new Date('2024-05-01'); // 替换成你的勒索攻击日期

  // 确定起始文件夹
  let startFolder = lastFolderId ? DriveApp.getFolderById(lastFolderId) : DriveApp.getRootFolder();

  const startTime = new Date().getTime();
  const maxRunTime = 28 * 60 * 1000; // 28分钟超时阈值

  // 获取当前文件夹及子文件夹的所有文件
  const allFiles = getAllFiles(startFolder);
  // 跳过已处理的文件
  const remainingFiles = allFiles.slice(currentIndex);

  for (let i = 0; i < remainingFiles.length; i++) {
    const file = remainingFiles[i];
    const fileId = file.getId();

    // 跳过已经处理过的文件
    if (processedFiles.includes(fileId)) continue;

    // 执行文件恢复逻辑(替换成你原来的处理代码)
    restoreTargetFile(file, attackDate);

    // 更新进度到脚本属性
    processedFiles.push(fileId);
    props.setProperty('processedFileIds', JSON.stringify(processedFiles));
    props.setProperty('currentFileIndex', currentIndex + i + 1);
    props.setProperty('lastProcessedFolderId', file.getParents().next().getId());

    // 检测是否接近超时
    const elapsed = new Date().getTime() - startTime;
    if (elapsed >= maxRunTime) {
      console.log('即将超时,保存进度后终止');
      return;
    }
  }

  // 全部处理完成,清空进度记录
  props.deleteAllProperties();
  console.log('所有文件处理完毕');
}

// 递归获取文件夹下所有文件(包含子文件夹)
function getAllFiles(folder) {
  let files = folder.getFiles();
  let result = [];
  while (files.hasNext()) {
    result.push(files.next());
  }
  let subFolders = folder.getFolders();
  while (subFolders.hasNext()) {
    result = result.concat(getAllFiles(subFolders.next()));
  }
  return result;
}

// 单个文件恢复逻辑:还原攻击前版本、修正文件名和修改时间
function restoreTargetFile(file, attackDate) {
  const versions = file.getVersions();
  let validVersion = null;
  // 找到攻击日期前的最后一个有效版本
  for (let version of versions) {
    if (version.getLastUpdated() < attackDate) {
      validVersion = version;
      break;
    }
  }
  if (validVersion) {
    // 恢复版本
    validVersion.restore();
    // 还原文件修改时间
    file.setLastUpdated(validVersion.getLastUpdated());
  }
}

// 续传直接调用主函数即可,无需额外写逻辑
function resumeRestore() {
  batchRestoreFiles();
}

额外建议

  • 直接运行batchRestoreFiles就行,它会自动判断是否续传
  • 可以给脚本加个定时触发器(比如每30分钟跑一次),实现自动续传直到所有文件处理完
  • 如果文件量特别大,把进度存在Drive的隐藏JSON文件里,避免ScriptProperties的存储上限不够用

内容的提问来源于stack exchange,提问作者Antonio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:07:42