修复Google Apps Script文件夹同步脚本中的文件名重复追加问题
修复Google Apps Script文件夹同步脚本中的文件名重复追加问题
我帮你分析下问题根源,再给出针对性的修复方案:
问题出在哪?
你遇到的文件名自动追加(1)甚至大量重复的情况,核心原因是Google Drive的makeCopy方法的默认行为:只要目标文件夹中曾经存在过同名文件(哪怕已经被移到回收站),Drive就会自动给新复制的文件加上序号后缀。哪怕你先把旧文件移到回收站,Drive的系统同步可能有延迟,复制操作还是会触发重命名逻辑。加上你的脚本是双向定时同步,反复触发后就会生成大量带序号的冗余文件。
另外,把旧文件移到回收站而不是彻底处理,也会让Drive一直“记住”这个文件名的存在,进一步加剧后缀问题。
修复方案一:直接更新文件内容(推荐)
最稳妥的方式是直接覆盖目标文件的内容,而不是删除旧文件再复制新文件。这样既不会产生新文件,也不会触发Drive的自动重命名逻辑,还能保留原文件的ID(对后续同步更友好)。
修改后的完整脚本如下:
function syncFolders() { const gbcFolderId = "<你的GB文件夹ID>"; const gbaFolderId = "<你的GBA文件夹ID>"; const gbcFolder = DriveApp.getFolderById(gbcFolderId); const gbaFolder = DriveApp.getFolderById(gbaFolderId); syncFolderFiles(gbcFolder, gbaFolder); // 从GB同步到GBA syncFolderFiles(gbaFolder, gbcFolder); // 从GBA同步到GB } function syncFolderFiles(sourceFolder, targetFolder) { const sourceFiles = sourceFolder.getFiles(); const targetFilesMap = createFileMap(targetFolder); while (sourceFiles.hasNext()) { const sourceFile = sourceFiles.next(); const sourceName = sourceFile.getName(); const sourceDate = sourceFile.getLastUpdated(); const targetFileInfo = targetFilesMap[sourceName]; // 如果目标文件不存在,或者源文件更新时间更新,才进行同步 if (!targetFileInfo || sourceDate > targetFileInfo.date) { if (targetFileInfo) { // 目标文件存在,直接覆盖内容 const targetFile = targetFileInfo.file; targetFile.setContentFromFile(sourceFile); // 更新目标文件的修改时间(可选,确保后续同步不会重复触发) targetFile.setLastUpdated(sourceDate); } else { // 目标文件不存在,直接复制(此时不会有重命名问题) sourceFile.makeCopy(sourceName, targetFolder); } } } } function createFileMap(folder) { const fileMap = {}; const files = folder.getFiles(); while (files.hasNext()) { const file = files.next(); fileMap[file.getName()] = { file: file, date: file.getLastUpdated(), }; } return fileMap; }
修复方案二:彻底移除旧文件后再复制
如果你更倾向于用“删除旧文件+复制新文件”的逻辑,需要确保旧文件被彻底从Drive中移除(而不是移到回收站)。不过这需要开启Google Drive高级服务,步骤如下:
- 在Google Apps Script编辑器中,点击「服务」→「添加服务」→ 选择「Drive API」并添加。
- 修改
syncFolderFiles函数中的删除逻辑:
function syncFolderFiles(sourceFolder, targetFolder) { const sourceFiles = sourceFolder.getFiles(); const targetFilesMap = createFileMap(targetFolder); while (sourceFiles.hasNext()) { const sourceFile = sourceFiles.next(); const sourceName = sourceFile.getName(); const sourceDate = sourceFile.getLastUpdated(); const targetFileInfo = targetFilesMap[sourceName]; if (targetFileInfo && targetFileInfo.date >= sourceDate) { continue; // 目标文件更新,跳过 } if (targetFileInfo) { // 彻底删除旧文件(而不是移到回收站) Drive.Files.remove(targetFileInfo.file.getId()); } // 此时目标文件夹无同名文件,复制不会加后缀 sourceFile.makeCopy(sourceName, targetFolder); } }
额外优化建议
- 缩小同步时间间隔:测试阶段可以用5分钟,但稳定后建议改成30分钟或1小时,减少不必要的同步触发。
- 添加时间差判断:在对比修改时间时,可以加一个10秒的缓冲(比如
sourceDate > targetFileInfo.date + 10000),避免因为Drive时间同步的微小误差导致反复同步。
备注:内容来源于stack exchange,提问作者pokemaniac
相关产品推荐
相关产品推荐

