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 將遠端目錄下載到本機資料夾並追蹤其進度。
Example
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);範例回應 (成功)
Response
{
"statusCode": 200,
"data": {
"errorCount": 0,
"count": 15,
"duration": 5.432,
"size": 2048576
}
}最佳實踐
篩選檔案
為了節省頻寬和時間,請使用 filter 函式僅下載您需要的檔案。例如,若要僅下載 JPEG 和 PNG 圖片:
Filtering Example
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 執行安全的單向同步。它根據檔案大小和最後修改時間進行比較。如果遠端檔案比其本機對應檔案更新或大小不同,則會下載該檔案。如果檔案存在於遠端但不存在於本機,則會在本機建立該檔案。重要的是,此指令不會刪除任何本機檔案,即使它們在遠端來源目錄中不存在。這使其成為一種非破壞性的方式,可讓本機資料夾保持最新狀態。