数据同步【免费下载链接】remotely-saveSync notes between local and cloud with smart conflict: S3 (Amazon S3/Cloudflare R2/Backblaze B2/...), Dropbox, webdav (NextCloud/InfiniCLOUD/Synology/...), OneDrive, Google Drive (GDrive), Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage.项目地址https://gitcode.com/gh_mirrors/re/remotely-save点击查看免费下载本文是 Remotely Save 同步算法系列文档中关于「忽略大文件」功能的专项技术指南。文章以 docs/sync_algorithm/sync_ignoring_large_files.md 为骨架结合仓库源码src/settings.ts、pro/src/sync.ts、src/fsEncrypt.ts 等深入剖析阈值配置方式、E2E 加密下尺寸比较的特殊规则、文件“跨越阈值线”时的拒绝行为以及各类同步场景下的判定分支帮助你完整理解并安全使用 Skip Large Files 功能。一、功能背景从“不忽略”到“可忽略”Remotely Save 插件在最初的设计中并不忽略任何大文件——所有文件无论体积多大都会参与本地与云端之间的同步。这虽然保证了数据的完整性但会带来两方面问题某些远程服务对单文件大小存在上传限制超大文件会导致同步失败用户可能希望将体积巨大的媒体文件如视频、音频、压缩包排除在同步范围之外只同步笔记相关的文本类文件。从 2022 年 5 月发布的新版本起插件提供了Skip Large Files跳过大文件功能可以设置一个大小阈值让所有尺寸超过该阈值的文件不再参与同步。但由于该功能是在已有同步体系之上叠加的插件必须制定一套与既有同步条件兼容的规则避免破坏已同步文件的既有状态这套规则正是本文的核心内容。二、阈值配置设置项与默认值2.1 设置界面入口在插件的「基础设置Basic」分区中有一个名为Skip Large Files的下拉菜单其描述文字为“Skip files with sizes larger than the threshold. Here 1 MB 10^6 bytes.”跳过大于某个阈值的文件。这里 1 MB 10⁶ 字节。对应的设置实现位于 src/settings.tsnew Setting(basicDiv) .setName(t(settings_skiplargefiles)) .setDesc(t(settings_skiplargefiles_desc)) .addDropdown((dropdown) { dropdown.addOption(-1, t(settings_skiplargefiles_notset)); const mbs [1, 5, 10, 20, 50, 100, 200, 500, 1000]; for (const mb of mbs) { dropdown.addOption(${mb * 1000 * 1000}, ${mb} MB); } dropdown .setValue(${this.plugin.settings.skipSizeLargerThan}) .onChange(async (val) { this.plugin.settings.skipSizeLargerThan Number.parseInt(val); await this.plugin.saveSettings(); }); });从源码可以看出关键信息项目说明默认值-1对应下拉菜单中的(not set)不设置即默认不忽略任何大文件可选档位1、5、10、20、50、100、200、500、1000 MB单位换算1 MB 10⁶ 字节1,000,000 字节而非二进制 1024×1024设置描述中已明确说明存储字段settings.skipSizeLargerThan以字节数为单位保存在插件配置中该配置字段在 src/baseTypes.ts 中声明为可选数字skipSizeLargerThan?: number;其默认值-1定义在 src/main.ts 的默认配置对象中skipSizeLargerThan: -1,2.2 阈值语义判定需要特别注意的是同步逻辑中对阈值的判断使用的是小于等于语义。以 pro/src/sync.ts 为例if ( skipSizeLargerThan 0 || remote.sizeEnc! skipSizeLargerThan ) {这里skipSizeLargerThan 0相当于“未设置阈值”的短路开关只要阈值小于等于 0默认-1所有文件都放行只有文件尺寸大于阈值时才会被忽略而尺寸恰好等于阈值的文件仍然正常同步。三、核心规则E2E 加密模式下比较“加密后尺寸”规则的第一条也是整个功能最容易产生误解的地方如果用户启用了 E2E端到端加密密码模式则文件大小的比较对象是“加密后的尺寸encrypted sizes”而不是原始未加密的文件大小。3.1 为什么要比较加密尺寸原文档给出了两点理由加密后的文件才是真正参与传输的对象——本地与远程之间实际传输的是加密后的字节流远程服务上的文件大小记录的就是加密尺寸加密尺寸可以从明文尺寸单向推导反向却不可行——从明文大小可以精确计算加密后的大小但从加密大小无法唯一反推出明文大小因为加密过程存在填充同一加密尺寸可能对应一段明文尺寸区间。因此以加密尺寸作为统一比较基准才能保证本地与远程两侧的判定口径一致。3.2 源码中的实现在 src/fsEncrypt.ts 的encryptEntity方法中当实体尚未填充sizeEnc时会从原始尺寸换算加密尺寸const local cloneDeep(input); if (local.sizeEnc undefined local.size ! undefined) { // its not filled yet, we fill it local.sizeEnc this._getSizeFromOrigToEnc(local.size); }换算方法_getSizeFromOrigToEnc在 src/fsEncrypt.ts 中按加密算法分派_getSizeFromOrigToEnc(x: number) { if (this.password ) { return x; } if (this.method openssl-base64) { return openssl.getSizeFromOrigToEnc(x); } else if (this.method rclone-base64) { return rclone.getSizeFromOrigToEnc(x); } else { throw Error(not supported encrypt method${this.method}); } }而实体统一数据结构中的sizeEnc字段定义在 src/baseTypes.tssize?: number; // might be unknown or to be filled sizeEnc?: number; sizeRaw: number;3.3 两种加密算法的尺寸换算细节OpenSSL 加密openssl-base64的换算实现在 src/encryptOpenSSL.tsexport const getSizeFromOrigToEnc (x: number) { if (x 0 || Number.isNaN(x) || !Number.isInteger(x)) { throw Error(getSizeFromOrigToEnc: x${x} is not a valid size); } return (Math.floor(x / 16) 1) * 16 16; }; export const getSizeFromEncToOrig (x: number) { if (x 32 || Number.isNaN(x) || !Number.isInteger(x)) { throw Error(getSizeFromEncToOrig: ${x} is not a valid size); } if (x % 16 ! 0) { throw Error( getSizeFromEncToOrig: ${x} is not a valid encrypted file size ); } return { minSize: ((x - 16) / 16 - 1) * 16, maxSize: ((x - 16) / 16 - 1) * 16 15, }; };可以看到每个明文文件加密后至少增加 16 字节的 salt 与 16 字节的填充以 16 字节块对齐。加密尺寸公式为(⌊x/16⌋ 1) × 16 16反向换算只能得到一个 15 字节宽的明文尺寸区间这正是“加密尺寸可由明文尺寸计算、反向却不可行”的数学基础。测试用例 tests/encryptOpenSSL.test.ts 验证了这一换算关系assert.equal(getSizeFromOrigToEnc(0), 32); assert.equal(getSizeFromOrigToEnc(15), 32); assert.equal(getSizeFromOrigToEnc(16), 48); assert.equal(getSizeFromOrigToEnc(31), 48); assert.equal(getSizeFromOrigToEnc(32), 64); assert.equal(getSizeFromOrigToEnc(14787203), 14787232);而rclone 加密rclone-base64则直接复用fyears/rclone-crypt包的encryptedSize函数见 src/encryptRClone.tsimport { Cipher as CipherRCloneCryptPack, encryptedSize, } from fyears/rclone-crypt; export const getSizeFromOrigToEnc encryptedSize;3.4 加密尺寸的实测佐证仓库测试资源 tests/static_assets/mona_lisa 提供了真实的加解密样本原始图片1374px-Mona_Lisa,..._retouched.jpg大小为 1,141,550 字节其加密产物1374px-Mona_Lisa,..._retouched.jpg.enc大小为 1,141,568 字节恰好相差 18 字节16 字节 salt 2 字节块内填充对齐与上述公式吻合。生成加密文件的命令记录在 tests/static_assets/mona_lisa/openssl_command.shopenssl enc -p -aes-256-cbc -S 8302F586FAB491EC -pbkdf2 -iter 10000 -pass pass:somepassword -in 1374px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg -out 1374px-Mona_Lisa,_by_Leonardo_da_Vinci,_from_C2RMF_retouched.jpg.enc3.5 加密模式下的实际阈值设定技巧由于比较的是加密尺寸用户在 E2E 加密模式下设置阈值时需要留意实际被拦截的明文文件大小会略小于阈值。例如设置阈值 1,000,000 字节时一个明文大小恰为 999,990 字节的文件加密后会膨胀到约 1,000,00x 字节从而被判定为“超过阈值”而忽略。若你的目标是“忽略明文大于某值的文件”应适当调高阈值档位以留出加密膨胀的余量。四、四象限判定文件“跨越阈值线”时拒绝同步规则的第二条针对的是已在本地与远程之间完成同步的文件 A。插件按本地尺寸与远程尺寸相对于阈值的分布分四种情况处理本地尺寸远程尺寸插件行为低于阈值低于阈值正常同步高于阈值高于阈值正常忽略低于阈值高于阈值拒绝同步并向用户抛出错误高于阈值低于阈值拒绝同步并向用户抛出错误其中第 3、4 种情况就是文档强调的核心观点——当文件大小“跨越了阈值线”即两侧对同一文件是否应忽略的判断不一致时插件不会自作主张引入更多麻烦如单侧删除或强制覆盖而是直接拒绝处理该文件并抛出错误把决策权交还给用户。需要注意的是该规则同样适用于删除操作。即当文件已同步、之后某一侧发生删除时也会应用相同的“跨越阈值线则拒绝”的判定避免在忽略大文件的状态下误删另一侧的副本。4.1 源码中的拒绝行为实现上述“拒绝并抛错”的行为在 pro/src/sync.ts 中体现为当单侧发生修改/删除、且该侧尺寸超过阈值时直接throw Error。例如 pro/src/sync.ts 中“本地未变、远程被修改”的分支branch 9if (localEqualPrevSync !remoteEqualPrevSync) { // If only one compares true (no prev also means it compares False), the other is modified. Backup and sync. if ( skipSizeLargerThan 0 || remote.sizeEnc! skipSizeLargerThan ) { // ... 正常执行 remote_is_modified_then_pull } else { throw Error( remote is modified (branch 9) but size larger than ${skipSizeLargerThan}, dont know what to do: ${JSON.stringify( mixedEntry )} ); } }同理还有“远程未变、本地被修改”branch 10pro/src/sync.ts、“远程被删除但本地修改”branch 5pro/src/sync.ts、“本地被删除但远程修改”branch 8pro/src/sync.ts等多个分支均在尺寸超限时抛出形如... but size larger than ${skipSizeLargerThan}, dont know what to do的错误并在错误信息中包含完整的实体数据JSON.stringify(mixedEntry)方便用户定位是哪个文件出了问题。4.2 新文件场景正常忽略与“跨越阈值线”的拒绝不同对于全新出现不在上一次同步记录中的单侧文件插件会直接静默忽略而不抛错。例如 pro/src/sync.ts 中“本地新建超大文件”的分支if (prevSync undefined) { // if A is not in the previous list, A is new if (skipSizeLargerThan 0 || local.sizeEnc! skipSizeLargerThan) { // ... 正常执行 local_is_created_then_push } else { mixedEntry.decisionBranch 37; mixedEntry.decision local_is_created_too_large_then_do_nothing; mixedEntry.change false; keptFolder.add(getParentFolder(key)); } }这里决策分支 37local_is_created_too_large_then_do_nothing意味着新建文件如果超过阈值直接标记为“什么都不做”不推送、不记录文件保留在本地但不会同步到远程。远程新建超大文件的处理逻辑与之对称见 pro/src/sync.ts 的 branch 28 场景。这是四象限规则之外最常用到的行为——大多数用户设置 Skip Large Files 的初衷正是让新增的大文件安静地留在本地。五、规则总结与实践建议5.1 规则要点速览默认不忽略任何文件skipSizeLargerThan -1需在设置中显式选择阈值档位11000 MB1 MB 10⁶ 字节E2E 加密模式下比较的是加密后尺寸且加密尺寸由明文尺寸单向可算、反向不可算两侧尺寸同为“低于阈值”则正常同步同为“高于阈值”则正常忽略两侧判定不一致跨越阈值线时拒绝同步并抛错删除场景同样适用全新单侧大文件无同步历史会被静默忽略不抛错、不传输。5.2 实践建议启用前先评估现有数据如果你已经同步过一批大文件再开启本功能那些“跨线”文件会导致同步报错。建议先在设置中把阈值调整到覆盖所有既有文件之上或先手动处理掉超限文件再开启忽略功能加密用户注意膨胀余量由于比较的是加密尺寸请为阈值预留约 2 KB 以上的加密膨胀空间具体取决于文件大小与加密算法报错即人工介入的信号当同步日志中出现but size larger than ... dont know what to do错误时意味着某个已同步文件跨越了阈值线需要你手动决定保留哪一侧然后重新同步新增大文件默认不报错如果你只是想“以后的大文件都别同步”直接设置阈值即可新建的超大文件会被静默忽略不会打断同步流程。六、延伸阅读同步算法的整体设计文档docs/sync_algorithm/README.md含 v1/v2/v3 三个版本的算法演进说明分别见 docs/sync_algorithm/v1/README.md、docs/sync_algorithm/v2/README.md、docs/sync_algorithm/v3/README.md同步决策分支与 mixed entity 的数据结构定义src/baseTypes.ts加密尺寸换算的完整单元测试tests/encryptOpenSSL.test.ts加密整体机制说明docs/encryption/README.md 与 docs/encryption/openssl.md。赞分享数据同步【免费下载链接】remotely-saveSync notes between local and cloud with smart conflict: S3 (Amazon S3/Cloudflare R2/Backblaze B2/...), Dropbox, webdav (NextCloud/InfiniCLOUD/Synology/...), OneDrive, Google Drive (GDrive), Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage.项目地址https://gitcode.com/gh_mirrors/re/remotely-save点击查看免费下载相关推荐Kubernetes负载均衡器Metallb网络策略完全指南如何配置允许与拒绝规则Kubernetes负载均衡器Metallb网络策略完全指南如何配置允许与拒绝规则 Metallb是一个专为裸金属Kubernetes集群设计的开源负载均衡器云原生网络创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考