OSS提供的分區上傳(Multipart Upload)功能,將要上傳的較大檔案(Object)分成多個分區(Part)來分別上傳,上傳完成後再調用CompleteMultipartUploadAsync介面將這些Part組合成一個Object。
注意事項
本文範例程式碼以華東1(杭州)的地區ID
cn-hangzhou為例,預設使用外網Endpoint,如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見地區和Endpoint。要分區上傳,您必須有
oss:PutObject許可權。具體操作,請參見為RAM使用者授予自訂的權限原則。
分區上傳流程
分區上傳(Multipart Upload)分為以下三個步驟:
初始化一個分區上傳事件。
調用Client.InitiateMultipartUploadAsync方法返回OSS建立的全域唯一的uploadID。
上傳分區。
調用Client.UploadPartAsync方法上傳分區資料。
說明對於同一個uploadID,分區號(partNumber)標識了該分區在整個檔案內的相對位置。如果使用同一個分區號上傳了新的資料,那麼OSS上該分區已有的資料將會被覆蓋。
OSS將收到的分區資料的MD5值放在ETag頭內返回給使用者。
OSS計算上傳資料的MD5值,並與SDK計算的MD5值比較,如果不一致則返回InvalidDigest錯誤碼。
完成分區上傳。
所有分區上傳完成後,調用Client.CompleteMultipartUploadAsync方法將所有分區合并成完整的檔案。
範例程式碼
以下代碼展示如何將本地的大檔案分割成多個分區檔案並發上傳到儲存空間,然後合并成完整的檔案對象。
using OSS = AlibabaCloud.OSS.V2; // 為阿里雲OSS SDK建立別名,簡化後續使用
var region = "cn-hangzhou"; // 必須項,設定Bucket所在的地區(Region)。以華東1(杭州)為例,Region填寫為cn-hangzhou
var endpoint = null as string; // 可選項,指定訪問OSS服務的網域名稱。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com
var bucket = "you bucket name"; // 必須項,Bucket名稱
var key = "your object key"; // 必須項,待上傳的目標檔案對象名稱
var partSize = 512*1024; // 必須項,每次上傳檔案的分區大小,以512*1024為例,每個分區大小512kb
var filePath = "filePath"; // 必須項,需上傳的目標檔案路徑
// 載入OSS SDK的預設配置,此配置會自動從環境變數中讀取憑證資訊(如AccessKey)
var cfg = OSS.Configuration.LoadDefault();
// 顯式設定使用環境變數擷取憑證,用於身分識別驗證(格式:OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET)
cfg.CredentialsProvider = new OSS.Credentials.EnvironmentVariableCredentialsProvider();
// 設定配置的Bucket地區
cfg.Region = region;
// 若已指定了endpoint,則覆蓋預設的endpoint
if(endpoint != null)
{
cfg.Endpoint = endpoint;
}
// 使用配置資訊建立OSS用戶端執行個體
using var client = new OSS.Client(cfg);
// 初始化分區上傳
var initResult = await client.InitiateMultipartUploadAsync(new()
{
Bucket = bucket,
Key = key
});
// 開啟要上傳的檔案
using var file = File.OpenRead(filePath);
long fileSize = file.Length;
long partNumber = 1;
// 儲存所有分區上傳後的資訊
var uploadParts = new List<OSS.Models.UploadPart>();
// 分塊上傳檔案
for (long offset = 0; offset < fileSize; offset += partSize)
{
// 計算當前分區的大小
var size = Math.Min(partSize, fileSize - offset);
// 上傳單個分區
var upResult = await client.UploadPartAsync(new()
{
Bucket = bucket,
Key = key,
PartNumber = partNumber,
UploadId = initResult.UploadId,
Body = new OSS.IO.BoundedStream(file, offset, size)
});
// 儲存分區資訊,用於後續完成上傳
uploadParts.Add(new() { PartNumber = partNumber, ETag = upResult.ETag });
partNumber++;
}
// 按分區號排序
uploadParts.Sort((left, right) => { return (left.PartNumber > right.PartNumber) ? 1 : -1; });
// 完成分區上傳
var cmResult = await client.CompleteMultipartUploadAsync(new()
{
Bucket = bucket,
Key = key,
UploadId = initResult.UploadId,
CompleteMultipartUpload = new ()
{
Parts = uploadParts
}
});
// 列印上傳結果
Console.WriteLine("MultipartUpload done"); // 提示操作完成
Console.WriteLine($"StatusCode: {cmResult.StatusCode}"); // HTTP狀態代碼
Console.WriteLine($"RequestId: {cmResult.RequestId}"); // RequestId,用於阿里雲排查問題
Console.WriteLine("Response Headers:"); // 回應標頭資訊
cmResult.Headers.ToList().ForEach(x => Console.WriteLine(x.Key + " : " + x.Value)); // 遍曆並列印所有回應標頭相關文檔
關於分區上傳的完整範例程式碼,請參見multipartUpload.cs。