拷貝檔案(Object)是指在不改變檔案內容的情況下,將同一地區下的源儲存空間(Bucket)內的檔案複製到目標Bucket,常用於資料備份、資料移轉。
使用限制
不支援跨地區拷貝Object。例如,不支援將華東1(杭州)地區下Bucket內的Object拷貝到華東2(上海)地區下的Bucket。
注意事項
如果要拷貝的檔案數量較多,直接指定拷貝後的檔案儲存體類型為深度冷歸檔類型會造成較高的PUT類請求費用。建議您通過生命週期規則將檔案轉儲為深度冷歸檔類型,從而降低PUT類請求費用。
您需要有源Object的讀許可權及目標Bucket的讀寫權限,否則無法完成拷貝操作。
拷貝檔案時,您需要確保源Bucket和目標Bucket均未設定合規保留原則,否則報錯The object you specified is immutable.。
拷貝檔案時預設會覆蓋同名檔案, 為防止檔案被意外覆蓋,您可以通過以下方式保護您的檔案。
開啟版本控制功能
開啟版本控制功能後,被刪除或覆蓋的檔案會以歷史版本的形式儲存下來。您可以隨時恢複歷史版本檔案。更多資訊,請參見版本控制概述。
在拷貝請求中攜帶禁止覆蓋同名檔案的參數
在拷貝請求的Header中攜帶 x-oss-forbid-overwrite參數,並指定其值為true。當您拷貝的檔案在目標Bucket中存在同名檔案時,該檔案將拷貝失敗,並返回
FileAlreadyExists錯誤。
操作步驟
使用圖形化管理工具ossbrowser
通過ossbrowser僅支援拷貝小於5 GB的檔案。關於如何使用ossbrowser拷貝檔案的具體操作,請參見常用操作。
使用阿里雲SDK
以下僅列舉常見SDK通過CopyObject方法拷貝小於1 GB檔案的程式碼範例。關於其他SDK的拷貝小於1 GB檔案以及通過UploadPartCopy方法拷貝大於1 GB檔案的程式碼範例,請參見SDK簡介。
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫源Bucket名稱。
String sourceBucketName = "srcexamplebucket";
// 填寫源Object的完整路徑。Object完整路徑中不能包含Bucket名稱。
String sourceKey = "srcexampleobject.txt";
// 填寫與源Bucket處於同一地區的目標Bucket名稱。
String destinationBucketName = "desexamplebucket";
// 填寫目標Object的完整路徑。Object完整路徑中不能包含Bucket名稱。
String destinationKey = "desexampleobject.txt";
// 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
String region = "cn-hangzhou";
// 建立OSSClient執行個體。
// 當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// 建立CopyObjectRequest對象。
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
// 設定新的檔案中繼資料。
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType("text/plain");
// 指定CopyObject操作時是否覆蓋同名目標Object。此處設定為true,表示禁止覆蓋同名Object。
// meta.setHeader("x-oss-forbid-overwrite", "true");
// 指定拷貝的源地址。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/recode-test.txt");
// 如果源Object的ETag值和您提供的ETag相等,則執行拷貝操作,並返回200 OK。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// 如果源Object的ETag值和您提供的ETag不相等,則執行拷貝操作,並返回200 OK。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// 如果指定的時間等於或者晚於檔案實際修改時間,則正常拷貝檔案,並返回200 OK。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// 如果源Object在指定時間後被修改過,則執行拷貝操作。
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// 指定設定目標Object中繼資料的方式。此處設定為COPY,表示複製源Object的中繼資料到目標Object。
// meta.setHeader(OSSHeaders.COPY_OBJECT_METADATA_DIRECTIVE, "COPY");
// 指定OSS建立目標Object時使用的伺服器端密碼編譯演算法。
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
// 表示KMS託管的使用者主要金鑰,該參數僅在x-oss-server-side-encryption為KMS時有效。
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****");
// 指定OSS建立目標Object時的存取權限,此處設定為Private,表示只有Object的擁有者和授權使用者有該Object的讀寫權限,其他使用者沒有許可權操作該Object。
// meta.setHeader(OSSHeaders.OSS_OBJECT_ACL, CannedAccessControlList.Private);
// 指定Object的儲存類型。此處設定為Standard,表示標準儲存類型。
// meta.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
// 指定Object的對象標籤,可同時設定多個標籤。
// meta.setHeader(OSSHeaders.OSS_TAGGING, "a:1");
// 指定設定目標Object對象標籤的方式。此處設定為COPY,表示複製源Object的對象標籤到目標Object。
// meta.setHeader(OSSHeaders.COPY_OBJECT_TAGGING_DIRECTIVE, "COPY");
copyObjectRequest.setNewObjectMetadata(meta);
// 複製檔案。
CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
} 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名稱。例如examplebucket。
bucket: 'examplebucket',
// 設定是否啟用HTTPS。設定secure為true時,表示啟用。
// secure: true
})
// 拷貝同一個Bucket中的檔案。
async function copySmallObjecInSameBucket() {
try {
// 填寫拷貝後和拷貝前的檔案完整路徑。檔案完整路徑中不能包含Bucket名稱。
// 設定目標檔案的HTTP頭和自訂目標檔案的中繼資料。
const result = await client.copy('destexampleobject.txt', 'srcexampleobject.txt', {
// 指定headers參數,設定目標檔案的HTTP頭。如果未指定headers參數,則目標檔案與源檔案的HTTP頭相同,即拷貝源檔案的HTTP頭。
headers: {
'Cache-Control': 'no-cache',
// 如果源Object的ETag值和您提供的ETag相等,則執行拷貝操作,並返回200 OK。
'if-match': '5B3C1A2E053D763E1B002CC607C5****',
// 如果源Object的ETag值和您提供的ETag不相等,則執行拷貝操作,並返回200 OK。
'if-none-match': '5B3C1A2E053D763E1B002CC607C5****',
// 如果指定的時間早於檔案實際修改時間,則執行拷貝操作,並返回200 OK。
'if-modified-since': '2021-12-09T07:01:56.000Z',
// 如果指定的時間晚於檔案實際修改時間,則執行拷貝操作,並返回200 OK。
'if-unmodified-since': '2021-12-09T07:01:56.000Z',
// 指定OSS建立目標Object時的存取權限,此處設定為private,表示只有Object的擁有者和授權使用者有該Object的讀寫權限,其他使用者沒有許可權操作該Object。
'x-oss-object-acl': 'private',
// 指定Object的對象標籤,可同時設定多個標籤。
'x-oss-tagging': 'Tag1=1&Tag2=2',
// 指定CopyObject操作時是否覆蓋同名目標Object。此處設定為true,表示禁止覆蓋同名Object。
'x-oss-forbid-overwrite': 'true',
},
// 指定meta參數,自訂目標檔案的中繼資料。如果未指定meta參數,目標檔案與源檔案的中繼資料相同,即拷貝源檔案的中繼資料。
meta: {
location: 'hangzhou',
year: 2015,
people: 'mary',
},
});
console.log(result);
} catch (e) {
console.log(e);
}
}
copySmallObjecInSameBucket()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";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";
// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();
// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;
// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
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);
}// 填寫源Bucket名稱。
String srcBucketName = "srcbucket";
// 填寫源Bucket內的Object完整路徑。
String srcObjectKey = "dir1/srcobject.txt";
// 填寫與源Bucket處於同一地區的目標Bucket名稱。
String destBucketName = "destbucket";
// 填寫目標Bucket內的Object完整路徑。
String destObjectKey = "dir2/destobject.txt";
// 建立Copy請求。
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketName, srcObjectKey, destBucketName, destObjectKey);
// ObjectMetadata objectMetadata = new ObjectMetadata();
// 設定Object的存取權限。此處設定有private,表示私人存取權限。
// objectMetadata.setHeader("x-oss-object-acl", "private");
// 設定Object儲存類型。此處設定為Standard,表示標準儲存類型。
// objectMetadata.setHeader("x-oss-storage-class", "Standard");
// 指定CopyObject操作時是否覆蓋同名目標Object。此處設定為true,表示禁止覆蓋同名Object。
// objectMetadata.setHeader("x-oss-forbid-overwrite", "true");
// 如果源Object的ETag值和您提供的ETag相等,則執行拷貝操作。
// objectMetadata.setHeader("x-oss-copy-source-if-match", "5B3C1A2E053D763E1B002CC607C5****");
// 指定拷貝的源地址。
// objectMetadata.setHeader("x-oss-copy-source", "/examplebucket/recode-test.txt");
// 如果源Object的ETag值和您提供的ETag不相等,則執行拷貝操作。
// objectMetadata.setHeader("x-oss-copy-source-if-none-match", "5B3C1A2E053D763E1B002CC607C5****");
// 如果指定的時間等於或者晚於檔案實際修改時間,則執行拷貝操作。
// objectMetadata.setHeader("x-oss-copy-source-if-unmodified-since", "2021-12-09T07:01:56.000Z");
// 如果源Object在指定時間後被修改過,則執行拷貝操作。
// objectMetadata.setHeader("x-oss-copy-source-if-modified-since", "2021-12-09T07:01:56.000Z");
// 指定設定目標Object中繼資料的方式。此處設定為COPY,表示複製源Object的中繼資料到目標Object。
// objectMetadata.setHeader("x-oss-metadata-directive", "COPY");
// 指定OSS建立目標Object時使用的伺服器端密碼編譯演算法。
// objectMetadata.setHeader("x-oss-server-side-encryption", "SSE-KMS");
// 表示KMS託管的使用者主要金鑰,該參數僅在x-oss-server-side-encryption為KMS時有效。
// objectMetadata.setHeader("x-oss-server-side-encryption-key-id", "9468da86-3509-4f8d-a61e-6eab1eac****");
// 指定Object的對象標籤,可同時設定多個標籤。
// objectMetadata.setHeader("x-oss-tagging", "a:1");
// 指定設定目標Object對象標籤的方式。此處設定為COPY,表示複製源Object的對象標籤到目標Object。
// objectMetadata.setHeader("x-oss-tagging-directive", "COPY");
// 非同步Copy。
OSSAsyncTask copyTask = oss.asyncCopyObject(copyObjectRequest, new OSSCompletedCallback<CopyObjectRequest, CopyObjectResult>() {
@Override
public void onSuccess(CopyObjectRequest request, CopyObjectResult result) {
Log.d("copyObject", "copy success!");
}
@Override
public void onFailure(CopyObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
// 請求異常。
if (clientExcepion != null) {
// 用戶端異常,例如網路異常等。
clientExcepion.printStackTrace();
}
if (serviceException != null) {
// 服務端異常。
Log.e("ErrorCode", serviceException.getErrorCode());
Log.e("RequestId", serviceException.getRequestId());
Log.e("HostId", serviceException.getHostId());
Log.e("RawMessage", serviceException.getRawMessage());
}
}
});OSSCopyObjectRequest * copy = [OSSCopyObjectRequest new];
// 填寫源Bucket名稱。
copy.sourceBucketName = @"sourcebucket";
// 填寫源Bucket內的Object完整路徑。
copy.sourceObjectKey = @"dir1/srcobject.txt";
// 填寫目標Bucket名稱。
copy.bucketName = @"destbucket";
// 填寫目標Bucket內的Object完整路徑。
copy.objectKey = @"dir2/destobject.txt";
NSMutableDictionary *objectMeta = [NSMutableDictionary dictionary];
// 設定存取權限。此處設定為private,表示私人許可權。
[objectMeta setValue:@"x-oss-object-acl" forKey:@"public-read"];
// 設定儲存類型。此處設定為Standard,表示標準儲存類型。
[objectMeta setValue:@"x-oss-storage-class" forKey:@"Standard"];
// 是否覆蓋同名Object。不指定x-oss-forbid-overwrite時,預設覆蓋同名Object。
// 指定x-oss-forbid-overwrite為false時,表示允許覆蓋同名Object。指定x-oss-forbid-overwrite為true時,表示禁止覆蓋同名Object,如果同名Object已存在,程式將報錯。
[objectMeta setValue:@"x-oss-forbid-overwrite" forKey:@"true"];
// 如果源Object的ETag值和您提供的ETag相等,則執行拷貝操作。
[objectMeta setValue:@"x-oss-copy-source-if-match" forKey:@"5B3C1A2E053D763E1B002CC607C5****"];
// 如果源Object的ETag值和您提供的ETag不相等,則執行拷貝操作。
[objectMeta setValue:@"x-oss-copy-source-if-none-match" forKey:@"5B3C1A2E053D763E1B002CC607C5****"];
// 如果檔案實際修改時間早於或等於2021-12-09T07:01:56.000Z,則執行拷貝操作。
[objectMeta setValue:@"x-oss-copy-source-if-unmodified-since" forKey:@"2021-12-09T07:01:56.000Z"];
// 如果檔案實際修改時間晚於2021-12-15T07:01:56.000Z,則執行拷貝操作。
[objectMeta setValue:@"x-oss-copy-source-if-modified-since" forKey:@"2021-12-15T07:01:56.000Z"];
// 複製源Object的中繼資料到目標Object。
[objectMeta setValue:@"x-oss-metadata-directive" forKey:@"COPY"];
// 複製源Object的對象標籤到目標Object。
[objectMeta setValue:@"x-oss-tagging-directive" forKey:@"Copy"];
// 指定OSS建立目標Object時使用的伺服器端密碼編譯演算法。
[objectMeta setValue:@"x-oss-server-side-encryption" forKey:@"KMS"];
// 表示KMS託管的使用者主要金鑰,該參數僅在x-oss-server-side-encryption為KMS時有效。
[objectMeta setValue:@"x-oss-server-side-encryption-key-id" forKey:@"9468da86-3509-4f8d-a61e-6eab1eac****"];
copy.objectMeta = objectMeta;
OSSTask * task = [client copyObject:copy];
[task continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"copy object success!");
} else {
NSLog(@"copy object failed, error: %@" , task.error);
}
return nil;
}];
// 實現同步阻塞等待任務完成。
// [task waitUntilFinished];#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* 初始化OSS帳號資訊。*/
/* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
std::string Endpoint = "yourEndpoint";
/* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
std::string Region = "yourRegion";
/* 填寫源Bucket名稱,例如srcexamplebucket。*/
std::string SourceBucketName = "srcexamplebucket";
/* 填寫與源Bucket處於同一地區的目標Bucket名稱,例如destbucket。*/
std::string CopyBucketName = "destbucket";
/* 填寫源Object的完整路徑,完整路徑中不能包含Bucket名稱,例如srcdir/scrobject.txt。*/
std::string SourceObjectName = "srcdir/scrobject.txt";
/* 填寫目標Object的完整路徑,完整路徑中不能包含Bucket名稱,例如destdir/destobject.txt。*/
std::string CopyObjectName = "destdir/destobject.txt";
/* 初始化網路等資源。*/
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
/* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
CopyObjectRequest request(CopyBucketName, CopyObjectName);
request.setCopySource(SourceBucketName, SourceObjectName);
/* 拷貝檔案。*/
auto outcome = client.CopyObject(request);
if (!outcome.isSuccess()) {
/* 異常處理。*/
std::cout << "CopyObject fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* 釋放網路等資源。*/
ShutdownSdk();
return 0;
}#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";
/* 填寫源Bucket名稱。*/
const char *source_bucket_name = "yourSourceBucketName";
/* 填寫源Object的完整路徑。Object完整路徑中不能包含Bucket名稱。*/
const char *source_object_name = "yourSourceObjectName";
/* 填寫與源Bucket處於同一地區的目標Bucket名稱。*/
const char *dest_bucket_name = "yourDestBucketName";
/* 填寫目標Object的完整路徑。Object完整路徑中不能包含Bucket名稱。*/
const char *dest_object_name = "yourDestObjectName";
/* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
const char *region = "yourRegion";
void init_options(oss_request_options_t *options)
{
options->config = oss_config_create(options->pool);
/* 用char*類型的字串初始化aos_string_t類型。*/
aos_str_set(&options->config->endpoint, endpoint);
/* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
//需要額外配置以下兩個參數
aos_str_set(&options->config->region, region);
options->config->signature_version = 4;
/* 是否使用了CNAME。0表示不使用。*/
options->config->is_cname = 0;
/* 用於設定網路相關參數,比如逾時時間等。*/
options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
/* 在程式入口調用aos_http_io_initialize方法來初始化網路、記憶體等全域資源。*/
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
exit(1);
}
/* 用於記憶體管理的記憶體池(pool),等價於apr_pool_t。其實現代碼在apr庫中。*/
aos_pool_t *pool;
/* 重新建立一個記憶體池,第二個參數是NULL,表示沒有繼承其它記憶體池。*/
aos_pool_create(&pool, NULL);
/* 建立並初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全域配置資訊。*/
oss_request_options_t *oss_client_options;
/* 在記憶體池中分配記憶體給options。*/
oss_client_options = oss_request_options_create(pool);
/* 初始化Client的選項oss_client_options。*/
init_options(oss_client_options);
/* 初始化參數。*/
aos_string_t source_bucket;
aos_string_t source_object;
aos_string_t dest_bucket;
aos_string_t dest_object;
aos_table_t *headers = NULL;
aos_table_t *resp_headers = NULL;
aos_status_t *resp_status = NULL;
aos_str_set(&source_bucket, source_bucket_name);
aos_str_set(&source_object, source_object_name);
aos_str_set(&dest_bucket, dest_bucket_name);
aos_str_set(&dest_object, dest_object_name);
headers = aos_table_make(pool, 0);
/* 拷貝檔案。*/
resp_status = oss_copy_object(oss_client_options, &source_bucket, &source_object, &dest_bucket, &dest_object, headers, &resp_headers);
if (aos_status_is_ok(resp_status)) {
printf("copy object succeeded\n");
} else {
printf("copy object failed\n");
}
/* 釋放記憶體池,相當於釋放了請求過程中各資源分派的記憶體。*/
aos_pool_destroy(pool);
/* 釋放之前分配的全域資源。*/
aos_http_io_deinitialize();
return 0;
}require 'aliyun/oss'
client = Aliyun::OSS::Client.new(
# 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
access_key_id: ENV['OSS_ACCESS_KEY_ID'],
access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)
# 填寫Bucket名稱,例如examplebucket。
bucket = client.get_bucket('examplebucket')
# 拷貝檔案並拷貝檔案中繼資料。
bucket.copy_object(
# 以將srcobject.txt拷貝為destobject.txt為例。
'destobject.txt', 'srcobject.txt',
:meta_directive => Aliyun::OSS::MetaDirective::COPY)
# 拷貝檔案並覆蓋檔案中繼資料。
bucket.copy_object(
'destobject.txt', 'srcobject.txt',
:metas => {'year' => '2017'},
:meta_directive => Aliyun::OSS::MetaDirective::REPLACE) package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定義全域變數
var (
region string // 儲存地區
srcBucketName string // 源儲存空間名稱
srcObjectName string // 來源物件名稱
destBucketName string // 目標儲存空間名稱
destObjectName string // 目標對象名稱
)
// init函數用於初始化命令列參數
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&srcBucketName, "src-bucket", "", "The name of the source bucket.")
flag.StringVar(&srcObjectName, "src-object", "", "The name of the source object.")
flag.StringVar(&destBucketName, "dest-bucket", "", "The name of the destination bucket.")
flag.StringVar(&destObjectName, "dest-object", "", "The name of the destination object.")
}
func main() {
// 解析命令列參數
flag.Parse()
// 檢查源bucket名稱是否為空白
if len(srcBucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source bucket name required")
}
// 檢查region是否為空白
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// 如果目標bucket名稱未指定,則使用源bucket名稱
if len(destBucketName) == 0 {
destBucketName = srcBucketName
}
// 檢查源object名稱是否為空白
if len(srcObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source object name required")
}
// 檢查目標object名稱是否為空白
if len(destObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, destination object name required")
}
// 載入預設配置並設定憑證提供者和地區
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 建立OSS用戶端
client := oss.NewClient(cfg)
// 建立複製對象請求
request := &oss.CopyObjectRequest{
Bucket: oss.Ptr(destBucketName), // 目標儲存空間名稱
Key: oss.Ptr(destObjectName), // 目標對象名稱
SourceKey: oss.Ptr(srcObjectName), // 來源物件名稱
SourceBucket: oss.Ptr(srcBucketName), // 源儲存空間名稱
}
// 執行複製對象操作並處理結果
result, err := client.CopyObject(context.TODO(), request)
if err != nil {
log.Fatalf("failed to copy object %v", err)
}
log.Printf("copy object result:%#v\n", result)
}
import argparse
import alibabacloud_oss_v2 as oss
# 建立命令列參數解析器
parser = argparse.ArgumentParser(description="copy object sample")
# 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令列參數 --bucket,表示目標儲存空間的名稱,必需參數
parser.add_argument('--bucket', help='The name of the destination bucket.', required=True)
# 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令列參數 --key,表示目標對象的名稱,必需參數
parser.add_argument('--key', help='The name of the destination object.', required=True)
# 添加命令列參數 --source_key,表示來源物件的名稱,必需參數
parser.add_argument('--source_key', help='The name of the source object.', required=True)
# 添加命令列參數 --source_bucket,表示源儲存空間的名稱,必需參數
parser.add_argument('--source_bucket', help='The name of the source bucket.', required=True)
def main():
# 解析命令列參數
args = parser.parse_args()
# 從環境變數中載入憑證資訊,用於身分識別驗證
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# 載入SDK的預設配置,並設定憑證提供者
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
# 設定配置中的地區資訊
cfg.region = args.region
# 如果提供了endpoint參數,則設定配置中的endpoint
if args.endpoint is not None:
cfg.endpoint = args.endpoint
# 使用配置好的資訊建立OSS用戶端
client = oss.Client(cfg)
# 執行複製對象的請求
result = client.copy_object(oss.CopyObjectRequest(
bucket=args.bucket, # 指定目標儲存空間名稱
key=args.key, # 指定目標對象鍵名
source_key=args.source_key, # 指定來源物件鍵名
source_bucket=args.source_bucket, # 指定源儲存空間名稱
))
# 輸出複製對象的結果資訊
print(f'status code: {result.status_code},'
f' request id: {result.request_id},'
f' version id: {result.version_id},'
f' hash crc64: {result.hash_crc64},'
f' source version id: {result.source_version_id},'
f' server side encryption: {result.server_side_encryption},'
f' server side data encryption: {result.server_side_data_encryption},'
f' last modified: {result.last_modified},'
f' etag: {result.etag},'
)
# 當此指令碼被直接運行時,調用main函數
if __name__ == "__main__":
main() # 指令碼入口,當檔案被直接運行時調用main函數<?php
// 引入自動負載檔案,確保依賴庫能夠正確載入
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// 定義命令列參數的描述資訊
$optsdesc = [
"region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地區(必填)
"endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 訪問網域名稱(可選)
"bucket" => ['help' => 'The name of the bucket', 'required' => True], // 目標Bucket名稱(必填)
"key" => ['help' => 'The name of the object', 'required' => True], // 目標對象名稱(必填)
"src-bucket" => ['help' => 'The name of the source bucket', 'required' => False], // 源Bucket名稱(可選)
"src-key" => ['help' => 'The name of the source object', 'required' => True], // 來源物件名稱(必填)
];
// 將參數描述轉換為getopt所需的長選項格式
// 每個參數後面加上":"表示該參數需要值
$longopts = \array_map(function ($key) {
return "$key:";
}, array_keys($optsdesc));
// 解析命令列參數
$options = getopt("", $longopts);
// 驗證必填參數是否存在
foreach ($optsdesc as $key => $value) {
if ($value['required'] === True && empty($options[$key])) {
$help = $value['help']; // 擷取參數的協助資訊
echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
exit(1); // 如果必填參數缺失,則退出程式
}
}
// 從解析的參數中提取值
$region = $options["region"]; // Bucket所在的地區
$bucket = $options["bucket"]; // 目標Bucket名稱
$key = $options["key"]; // 目標對象名稱
$srcKey = $options["src-key"]; // 來源物件名稱
// 載入環境變數中的憑證資訊
// 使用EnvironmentVariableCredentialsProvider從環境變數中讀取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 設定憑證提供者
$cfg->setRegion($region); // 設定Bucket所在的地區
if (isset($options["endpoint"])) {
$cfg->setEndpoint($options["endpoint"]); // 如果提供了訪問網域名稱,則設定endpoint
}
// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);
// 建立CopyObjectRequest對象,用於複製對象
$request = new Oss\Models\CopyObjectRequest(
bucket: $bucket,
key: $key);
if (!empty($options["src-bucket"])) {
$request->sourceBucket = $options["src-bucket"]; // 如果提供了源Bucket名稱,則設定sourceBucket
}
$request->sourceKey = $srcKey; // 設定來源物件名稱
// 執行複製對象操作
$result = $client->copyObject($request);
// 列印複製結果
printf(
'status code:' . $result->statusCode . PHP_EOL . // HTTP狀態代碼,例如200表示成功
'request id:' . $result->requestId . PHP_EOL // 請求ID,用於調試或追蹤請求
);
使用命令列工具ossutil
您可以使用命令列工具ossutil來拷貝檔案,ossutil的安裝請參見安裝ossutil。
以下樣本展示了如何拷貝儲存空間srcBucket下的srcObject到儲存空間examplebucket下的exampleobject。
ossutil api copy-object --bucket examplebucket --key exampleobject --copy-source /srcBucket/srcObject關於該命令的更多資訊,請參見copy-object。
相關API
以上操作方式底層基於以下API,如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見CopyObject。