本文介紹如何將源Bucket中的檔案(Object)複製到同一地區下相同或不同目標Bucket中。
注意事項
本文以華東1(杭州)外網Endpoint為例。如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見訪問網域名稱和資料中心。
本文以OSS網域名稱建立OSSClient為例。如果您希望通過自訂網域名、STS等方式建立OSSClient,請參見初始化。
拷貝檔案時,您必須擁有源檔案的讀許可權及目標Bucket的讀寫權限。
拷貝檔案時,您需要確保源Bucket和目標Bucket均未設定合規保留原則,否則報錯The object you specified is immutable.。
不支援跨地區拷貝。例如不能將華東1(杭州)地區儲存空間中的檔案拷貝到華北1(青島)地區。
拷貝小檔案
以下代碼用於拷貝小檔案:
using Aliyun.OSS;
using Aliyun.OSS.Common;
// 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫源Bucket名稱,例如srcexamplebucket。
var sourceBucket = "srcexamplebucket";
// 填寫源Object的完整路徑,完整路徑中不能包含Bucket名稱,例如srcdir/scrobject.txt。
var sourceObject = "srcdir/scrobject.txt";
// 填寫與源Bucket處於同一地區的目標Bucket名稱,例如destbucket。
var targetBucket = "destbucket";
// 填寫目標Object的完整路徑,完整路徑中不能包含Bucket名稱,例如destdir/destobject.txt。
var targetObject = "destdir/destobject.txt";
// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
var metadata = new ObjectMetadata();
// 設定自訂中繼資料。自訂中繼資料為索引值對(Key-Value)的形式,例如Key為mk1,Value為mv1。
metadata.AddHeader("mk1", "mv1");
metadata.AddHeader("mk2", "mv2");
var req = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject)
{
// 如果NewObjectMetadata為null則為COPY模式(即拷貝源檔案的中繼資料),非null則為REPLACE模式(覆蓋源檔案的中繼資料)。
NewObjectMetadata = metadata
};
// 拷貝檔案。
client.CopyObject(req);
Console.WriteLine("Copy object succeeded");
}
catch (OssException ex)
{
Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID: {2} \tHostID: {3}",
ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
Console.WriteLine("Failed with error info: {0}", ex.Message);
}
拷貝大檔案
分區拷貝
對於大於1 GB的檔案,需要使用分區拷貝(UploadPartCopy)。分區拷貝分為三步:
使用InitiateMultipartUploadRequest方法來初始化一個分區上傳事件。
使用UploadPartCopy方法進行分區拷貝。
使用CompleteMultipartUpload方法完成檔案拷貝。
以下代碼用於分區拷貝檔案:
using Aliyun.OSS; using Aliyun.OSS.Common; // 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。 var endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID"); var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET"); // 填寫源Bucket名稱,例如srcexamplebucket。 var sourceBucket = "srcexamplebucket"; // 填寫源Object的完整路徑,完整路徑中不能包含Bucket名稱,例如srcdir/scrobject.txt。 var sourceObject = "srcdir/scrobject.txt"; // 填寫與源Bucket處於同一地區的目標Bucket名稱,例如destbucket。 var targetBucket = "destbucket"; // 填寫目標Object的完整路徑,完整路徑中不能包含Bucket名稱,例如destdir/destobject.txt。 var targetObject = "destdir/destobject.txt"; var uploadId = ""; var partSize = 50 * 1024 * 1024; // 建立OssClient執行個體。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); try { // 初始化拷貝任務。可以通過InitiateMultipartUploadRequest指定目標檔案中繼資料。 var request = new InitiateMultipartUploadRequest(targetBucket, targetObject); var result = client.InitiateMultipartUpload(request); // 列印uploadId。 uploadId = result.UploadId; Console.WriteLine("Init multipart upload succeeded, Upload Id: {0}", result.UploadId); // 計算分區數。 var metadata = client.GetObjectMetadata(sourceBucket, sourceObject); var fileSize = metadata.ContentLength; var partCount = (int)fileSize / partSize; if (fileSize % partSize != 0) { partCount++; } // 開始分區拷貝。 var partETags = new List<PartETag>(); for (var i = 0; i < partCount; i++) { var skipBytes = (long)partSize * i; var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes); // 建立UploadPartCopyRequest。可以通過UploadPartCopyRequest指定限定條件。 var uploadPartCopyRequest = new UploadPartCopyRequest(targetBucket, targetObject, sourceBucket, sourceObject, uploadId) { PartSize = size, PartNumber = i + 1, // BeginIndex用來定位此次上傳分區開始所對應的位置。 BeginIndex = skipBytes }; // 調用uploadPartCopy方法來拷貝每一個分區。 var uploadPartCopyResult = client.UploadPartCopy(uploadPartCopyRequest); Console.WriteLine("UploadPartCopy : {0}", i); partETags.Add(uploadPartCopyResult.PartETag); } // 完成分區拷貝。 var completeMultipartUploadRequest = new CompleteMultipartUploadRequest(targetBucket, targetObject, uploadId); // partETags為分區上傳中儲存的partETag的列表,OSS收到使用者提交的此列表後,會逐一驗證每個資料分區的有效性。全部驗證通過後,OSS會將這些分區合成一個完整的檔案。 foreach (var partETag in partETags) { completeMultipartUploadRequest.PartETags.Add(partETag); } var completeMultipartUploadResult = client.CompleteMultipartUpload(completeMultipartUploadRequest); Console.WriteLine("CompleteMultipartUpload succeeded"); } catch (OssException ex) { Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID: {2} \tHostID: {3}", ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId); } catch (Exception ex) { Console.WriteLine("Failed with error info: {0}", ex.Message); }
斷點續傳拷貝
如果拷貝中斷,可通過斷點續傳繼續拷貝。
以下代碼用於斷點續傳拷貝:
using Aliyun.OSS; // 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。 var endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID"); var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET"); // 填寫源Bucket名稱,例如srcexamplebucket。 var sourceBucket = "srcexamplebucket"; // 填寫源Object的完整路徑,完整路徑中不能包含Bucket名稱,例如srcdir/scrobject.txt。 var sourceObject = "srcdir/scrobject.txt"; // 填寫與源Bucket處於同一地區的目標Bucket名稱,例如destbucket。 var targetBucket = "destbucket"; // 填寫目標Object的完整路徑,完整路徑中不能包含Bucket名稱,例如destdir/destobject.txt。 var targetObject = "destdir/destobject.txt"; // 記錄拷貝結果的檔案。拷貝過程中的進度資訊會儲存在該檔案中,如果拷貝失敗,再次拷貝時會根據檔案中記錄的點繼續拷貝。拷貝完成後,該檔案會被刪除。 var checkpointDir = @"yourCheckpointDir"; // 建立OssClient執行個體。 var client = new OssClient(endpoint, accessKeyId, accessKeySecret); try { var request = new CopyObjectRequest(sourceBucket, sourceObject, targetBucket, targetObject); // checkpointDir目錄中會儲存斷點續傳的中間狀態,用於失敗後,下次繼續拷貝。如果checkpointDir為null,斷點續傳功能不會生效,每次都會重新拷貝。 client.ResumableCopyObject(request, checkpointDir); Console.WriteLine("Resumable copy new object:{0} succeeded", request.DestinationKey); } catch (Exception ex) { Console.WriteLine("Resumable copy new object failed, {0}", ex.Message); }
相關文檔
拷貝小檔案
關於拷貝小檔案的完整範例程式碼,請參見GitHub樣本。
關於拷貝小檔案的API介面說明,請參見CopyObject。
拷貝大檔案
關於拷貝大檔案的完整範例程式碼,請參見GitHub樣本。
關於拷貝大檔案的API介面說明,請參見UploadPartCopy。
斷點續傳拷貝
關於斷點續傳拷貝的完整範例程式碼,請參見GitHub樣本。