SyncFolderPullCommand 是一个高级命令,旨在将 DID Space 中的远程目录同步到本地文件夹。它会智能地比较远程源和本地目标之间的文件,仅下载新的或已更新的文件。这能有效地确保您的本地目录是远程数据的最新镜像。
此命令与 SyncFolderPushCommand 相对应,后者用于将本地更改上传到远程目录。
用例
此命令非常适用于需要从用户的 Space 中检索文件集合的场景。常见用例包括:
- 将用户的相册下载到本地应用程序。
- 将应用程序数据的备份从 Space 恢复到本地计算机。
- 保持本地工作区与存储在 Space 中的主版本同步。
输入参数
该命令的构造函数接受一个包含以下字段的对象:
- source
string(required) — 要从中拉取文件的 DID Space 中的源目录路径。该路径应以“/”结尾。 - target
string(required) — 文件将下载到您的本地文件系统中的目标路径。如果该目录不存在,命令将自动创建它。 - concurrency
number(default:4) — 并行下载的文件数量。对于包含许多小文件的目录,增加此值可以加快处理速度。最大值受可用 CPU 核心数的限制。 - retryCount
number(default:3) — 在将特定文件标记为错误之前,重试失败下载的次数。最大值为 10。 - filter
(object: Object) => boolean— 为每个远程对象调用的函数。返回 true 以将对象包含在同步过程中,或返回 false 以跳过它。这对于根据文件属性(如名称或大小)选择性下载文件非常有用。 - onProgress
(params: OnProgressInput) => void— 每个文件开始下载过程时触发的回调函数。它会接收一个包含当前进度的对象。- completed
number— 已开始下载的文件数量。 - total
number— 要下载的文件总数。 - key
string— 当前正在处理的文件的键(相对路径)。
- completed
- onAfterUpload
(params: OnAfterUploadInput) => void— 每个文件成功下载后触发的回调函数。注意:尽管名称为“onAfterUpload”,但对于拉取命令,它表示下载完成。- completed
number— 到目前为止已成功下载的文件数量。 - total
number— 要下载的文件总数。 - key
string— 刚刚完成下载的文件的键(相对路径)。
- completed
- debug
boolean(default:false) — 设置为 true 以在控制台中启用详细日志记录,这有助于调试同步过程。 - strictSync
boolean(default:false) — 此参数对 SyncFolderPullCommand 无效。该命令被设计为对本地目录非破坏性的,不会删除远程源中不存在的本地文件。
输出
spaceClient.send() 方法返回一个 promise,该 promise 会解析为一个包含操作结果的对象。
- statusCode
number— 表示请求的结果。值为 200 表示整个同步操作成功完成。 - data
object— 包含同步操作摘要的对象。- count
number— 计划下载的文件总数。 - errorCount
number— 在所有重试后下载失败的文件数量。 - size
number— 所有成功下载文件的总大小(以字节为单位)。 - duration
number— 操作所花费的总时间(以秒为单位)。
- count
- statusMessage
string— 如果整个命令执行失败(例如,由于身份验证问题),则会显示错误消息。 - stack
string— 如果发生不可恢复的错误,则为堆栈跟踪。
示例
以下是如何使用 SyncFolderPullCommand 将远程目录下载到本地文件夹并跟踪其进度。
示例
import { SpaceClient, SyncFolderPullCommand } from '@blocklet/did-space-js';
import getWallet from '@blocklet/sdk/lib/wallet';
import { ensureDirSync, removeSync } from 'fs-extra';
import path from 'path';
const main = async () => {
// 1. 初始化 SpaceClient
const wallet = getWallet();
const spaceClient = new SpaceClient({
endpoint: 'https://www.didspaces.com/app/api/space/...',
wallet,
});
// 2. 准备用于下载的本地目录
const localTarget = path.join(__dirname, 'my-pulled-assets');
removeSync(localTarget); // 为此示例清理之前的运行
ensureDirSync(localTarget);
console.log(`Downloading files to: ${localTarget}`);
// 3. 创建并发送命令
const command = new SyncFolderPullCommand({
source: '/shared-media/', // 要从中拉取的 Space 中的目录
target: localTarget, // 要下载到的本地目录
onProgress: ({ completed, total, key }) => {
const progress = total > 0 ? ((completed / total) * 100).toFixed(2) : 0;
console.log(`Progress: ${progress}% (${completed}/${total}) - Starting download for: ${key}`);
},
});
const output = await spaceClient.send(command);
// 4. 处理输出
if (output.statusCode === 200) {
console.log('\nFolder pull completed successfully!');
console.log(`Total files synchronized: ${output.data.count}`);
console.log(`Total size: ${(output.data.size / 1024).toFixed(2)} KB`);
console.log(`Duration: ${output.data.duration.toFixed(2)}s`);
console.log(`Errors: ${output.data.errorCount}`);
} else {
console.error(`Folder pull failed with status ${output.statusCode}:`, output.statusMessage);
}
};
main().catch(console.error);示例响应(成功)
响应
{
"statusCode": 200,
"data": {
"errorCount": 0,
"count": 15,
"duration": 5.432,
"size": 2048576
}
}最佳实践
筛选文件
为节省带宽和时间,请使用 filter 函数仅下载您需要的文件。例如,仅下载 JPEG 和 PNG 图片:
筛选示例
const command = new SyncFolderPullCommand({
source: '/photos/',
target: './downloaded_images',
filter: (object) => {
// 跳过目录和非图像文件
if (object.isDir) return false;
const lowerCaseKey = object.key.toLowerCase();
return lowerCaseKey.endsWith('.jpg') || lowerCaseKey.endsWith('.png');
},
});理解同步逻辑
SyncFolderPullCommand 执行安全的单向同步。它根据文件大小和最后修改时间来比较文件。如果远程文件比其本地对应文件更新或大小不同,则会下载该文件。如果文件存在于远程但本地不存在,则会在本地创建该文件。至关重要的是,此命令不会删除任何本地文件,即使它们在远程源目录中不存在。这使其成为一种保持本地文件夹更新的非破坏性方式。