OSS提供的分區上傳(Multipart Upload)功能,將要上傳的較大檔案(Object)分成多個分區(Part)來分別上傳,上傳完成後再調用CompleteMultipartUpload介面將這些Part組合成一個Object來達到斷點續傳的效果。
背景資訊
當需要上傳的檔案較大時,您可以通過MultipartUpload
方法進行分區上傳。分區上傳是指將要上傳的檔案分成多個資料區塊(Part)來分別上傳。當其中一些分區上傳失敗後,OSS將保留上傳進度記錄。當您再次重傳時,只需要上傳失敗的分區,不需要重新上傳整個檔案。
通常在檔案大於100 MB的情況下,建議採用分區上傳的方法,通過斷點續傳和重試,提高上傳成功率。如果在檔案小於100 MB的情況下使用分區上傳,且partSize設定不合理的情況下,可能會出現無法完整顯示上傳進度的情況。對於小於100 MB的檔案,建議使用簡單上傳的方式。
在使用MultipartUpload
方法時,如果遇到ConnectionTimeoutError
逾時問題,業務方需自行處理逾時邏輯。例如通過縮小分區大小、增加逾時時間、重試請求或者捕獲ConnectionTimeoutError
錯誤等方法處理逾時。更多資訊,請參見網路錯誤處理。
分區上傳涉及的相關參數說明請參見下表。
類型 | 參數 | 說明 |
必選參數 | name {String} | Object完整路徑,Object完整路徑中不能包含Bucket名稱。 |
file {String|File} | 表示檔案路徑或者HTML5檔案。 | |
[options] {Object} 選擇性參數 | [checkpoint] {Object} | 記錄本地分區上傳結果的檔案。開啟斷點續傳功能時需要設定此參數,上傳過程中的進度資訊會儲存在該檔案中,如果某一分區上傳失敗,再次上傳時會根據檔案中記錄的點繼續上傳。上傳完成後,該檔案會被刪除。 |
[parallel] {Number} | 並發上傳的分區個數,預設值為5。如果無特殊需求,無需手動設定此參數。 | |
[partSize] {Number} | 指定上傳的每個分區的大小,範圍為100 KB~5 GB。單個分區預設大小為1 * 1024 * 1024(即1 MB)。如果無特殊需求,無需手動設定此參數。 | |
[progress] {Function} | 表示進度回呼函數,用於擷取上傳進度,可以是async的函數形式。回呼函數包含三個參數:
| |
[meta] {Object} | 使用者自訂的Header meta資訊,Header首碼為 | |
[mime] {String} | 設定Content-Type要求標頭。 | |
[headers] {Object} | 其他Header。更多資訊,請參見RFC 2616。其中:
|
分區上傳完整樣本
Node.js分區上傳過程中不支援MD5校正。建議分區上傳完成後調用CRC64庫自行判斷是否進行CRC64校正。
以下代碼通過multipartUpload
方法進行分區上傳。
const OSS = require('ali-oss');
const path = require("path");
const client = new OSS({
// yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
region: 'yourregion',
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
authorizationV4: true,
// 填寫儲存空間名稱。
bucket: 'yourbucketname',
});
const progress = (p, _checkpoint) => {
// Object的上傳進度。
console.log(p);
// 分區上傳的斷點資訊。
console.log(_checkpoint);
};
const headers = {
// 指定Object的儲存類型。
'x-oss-storage-class': 'Standard',
// 指定Object標籤,可同時設定多個標籤。
'x-oss-tagging': 'Tag1=1&Tag2=2',
// 指定初始化分區上傳時是否覆蓋同名Object。此處設定為true,表示禁止覆蓋同名Object。
'x-oss-forbid-overwrite': 'true'
}
// 開始分區上傳。
async function multipartUpload() {
try {
// 依次填寫Object完整路徑(例如exampledir/exampleobject.txt)和本地檔案的完整路徑(例如D:\\localpath\\examplefile.txt)。Object完整路徑中不能包含Bucket名稱。
// 如果本地檔案的完整路徑中未指定本地路徑(例如examplefile.txt),則預設從樣本程式所屬專案對應本地路徑中上傳檔案。
const result = await client.multipartUpload('exampledir/exampleobject.txt', path.normalize('D:\\localpath\\examplefile.txt'), {
progress,
// headers,
// 指定meta參數,自訂Object的中繼資料。通過head介面可以擷取到Object的meta資料。
meta: {
year: 2020,
people: 'test',
},
});
console.log(result);
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
const head = await client.head('exampledir/exampleobject.txt');
console.log(head);
} catch (e) {
// 捕獲逾時異常。
if (e.code === 'ConnectionTimeoutError') {
console.log('TimeoutError');
// do ConnectionTimeoutError operation
}
console.log(e);
}
}
multipartUpload();
以上分區上傳完整樣本調用的方法multipartUpload
中封裝了初始化分區上傳、上傳分區以及完成分區上傳三個API介面。如果您希望分步驟實現分區上傳,請依次調用.initMultipartUpload、.uploadPart以及.completeMultipartUpload方法。
取消分區上傳事件
您可以調用client.abortMultipartUpload
方法來取消分區上傳事件。當一個分區上傳事件被取消後,無法再使用該uploadId做任何操作,已經上傳的分區資料會被刪除。
以下代碼用於取消分區上傳事件。
const OSS = require("ali-oss");
const client = new OSS({
// yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
region: "yourregion",
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
authorizationV4: true,
// 填寫儲存空間名稱。
bucket: "yourbucketname",
});
async function abortMultipartUpload() {
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
const name = "exampledir/exampleobject.txt";
// 填寫uploadId。uploadId來源於調用InitiateMultipartUpload完成初始化分區之後的返回結果。
const uploadId = "0004B999EF518A1FE585B0C9360D****";
const result = await client.abortMultipartUpload(name, uploadId);
console.log(result);
}
abortMultipartUpload();
列舉分區上傳事件
調用client.listUploads
方法列舉出所有執行中的分區上傳事件,即已初始化但尚未完成或尚未取消的分區上傳事件。
const OSS = require("ali-oss");
const client = new OSS({
// yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
region: "yourregion",
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
authorizationV4: true,
// 填寫儲存空間名稱。
bucket: "yourbucketname",
});
async function listUploads(query = {}) {
// query中支援設定prefix、marker、delimiter、upload-id-marker和max-uploads參數。
const result = await client.listUploads(query);
result.uploads.forEach((upload) => {
// 分區上傳的uploadId。
console.log(upload.uploadId);
// 將所有上傳完成後的分區(Part)組合為一個完整的Object,並指定Object完整路徑。
console.log(upload.name);
});
}
const query = {
// 指定此次返回Multipart Uploads事件的最大個數。max-uploads參數的預設值和最大值均為1000。
"max-uploads": 1000,
};
listUploads(query);
列舉已上傳的分區
分區上傳過程中,調用client.listParts
方法列舉指定uploadId下所有已經上傳成功的分區。
const OSS = require("ali-oss");
const client = new OSS({
// yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
region: "yourregion",
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
authorizationV4: true,
// 填寫儲存空間名稱。
bucket: "yourbucketname",
});
async function listParts() {
const query = {
// 指定此次返回的最大分區(Part)個數。max-parts參數的預設值和最大值均為1000。
"max-parts": 1000,
};
let result;
do {
result = await client.listParts(
// 填寫Object完整路徑(例如exampledir/exampleobject.txt)。Object完整路徑中不能包含Bucket名稱。
"exampledir/exampleobject.txt",
// uploadId來源於調用InitiateMultipartUpload完成初始化分區之後,且在調用CompleteMultipartUpload完成分區上傳之前的返回結果
"0004B999EF518A1FE585B0C9360D****",
query
);
// 指定下次列舉分區的起始位置,只有分區號大於此參數值的分區會被列舉。
query["part-number-marker"] = result.nextPartNumberMarker;
result.parts.forEach((part) => {
console.log(part.PartNumber);
console.log(part.LastModified);
console.log(part.ETag);
console.log(part.Size);
});
} while (result.isTruncated === "true");
}
listParts();
相關文檔
關於分區上傳的完整範例程式碼,請參見GitHub樣本。
Node.js SDK分區上傳調用的方法
multipartUpload
中封裝了三個API介面,詳情如下:關於初始化分區上傳事件的API介面說明,請參見InitiateMultipartUpload。
關於分區上傳Part的API介面說明,請參見UploadPart。
關於完成分區上傳的API介面說明,請參見CompleteMultipartUpload。
關於取消分區上傳事件的API介面說明,請參見AbortMultipartUpload。
關於列舉已上傳分區的API介面說明,請參見ListParts。
關於列舉所有執行中的分區上傳事件(即已初始化但尚未完成或尚未取消的分區上傳事件)的API介面說明,請參見ListMultipartUploads。