本文介紹如何在受版本控制的儲存空間(Bucket)中上傳檔案(Object)。
注意事項
本文以華東1(杭州)外網Endpoint為例。如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見OSS地區和訪問網域名稱。
本文以OSS網域名稱建立OSSClient為例。如果您希望通過自訂網域名、STS等方式建立OSSClient,請參見建立OssClient。
要上傳檔案,您必須有
oss:PutObject
許可權。具體操作,請參見為RAM使用者授權自訂的權限原則。
簡單上傳
在已開啟版本控制的Bucket中,OSS會為新添加的Object自動產生唯一的版本ID,並在響應header中通過x-oss-version-id形式返回。在暫停了版本控制的Bucket中,新添加的Object的版本ID為“null”,上傳同名Object,後一次會覆蓋前一次上傳的檔案內容。OSS保證同一個Object只會有一個版本ID為“null”。
以下代碼用於簡單上傳:
#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名稱,例如examplebucket。*/
std::string BucketName = "examplebucket";
/* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
std::string ObjectName = "exampledir/exampleobject.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);
std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
*content << "test cpp sdk";
PutObjectRequest request(BucketName, ObjectName, content);
/* 上傳檔案。*/
auto outcome = client.PutObject(request);
if (outcome.isSuccess()) {
std::cout << "versionid:" << outcome.result().VersionId() << std::endl;
}
else {
/* 異常處理。*/
std::cout << "PutObject fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* 釋放網路等資源。*/
ShutdownSdk();
return 0;
}
追加上傳
在受版本控制的Bucket中,僅支援對於目前的版本為Appendable類型的Object執行追加(AppendObject)操作,不支援對於歷史版本為Appendable類型的Object執行AppendObject操作。
對目前的版本為Appendable類型的Object執行AppendObject操作時,OSS不會為該Appendable類型的Object產生歷史版本。
對目前的版本為Appendable類型的Object執行PutObject或DeleteObject操作時,OSS會將該Appendable類型的Object保留為歷史版本,且該Object不允許繼續追加。
不支援對目前的版本為非Appendable類型的Object(包括Normal Object、Delete Marker等)執行AppendObject操作。
以下代碼用於追加上傳:
#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名稱,例如examplebucket。*/
std::string BucketName = "examplebucket";
/* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
std::string ObjectName = "exampledir/exampleobject.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);
auto meta = ObjectMetaData();
meta.setContentType("text/plain");
/* 第一次追加的位置是0,傳回值為下一次追加的位置。後續追加的位置是追加前檔案的長度。*/
std::shared_ptr<std::iostream> content1 = std::make_shared<std::stringstream>();
*content1 <<"Thank you for using Aliyun Object Storage Service!";
AppendObjectRequest request(BucketName, ObjectName, content1, meta);
request.setPosition(0L);
/* 第一次追加檔案。*/
auto result = client.AppendObject(request);
/* 查看本次執行追加檔案的object的版本ID。*/
if (result.isSuccess()) {
std::cout << "versionid:" << result.result().VersionId() << std::endl;
}
else {
/* 異常處理。*/
std::cout << "AppendObject fail" <<
",code:" << result.error().Code() <<
",message:" << result.error().Message() <<
",requestId:" << result.error().RequestId() << std::endl;
return -1;
}
std::shared_ptr<std::iostream> content2 = std::make_shared<std::stringstream>();
*content2 <<"Thank you for using Aliyun Object Storage Service!";
auto position = result.result().Length();
AppendObjectRequest appendObjectRequest(BucketName, ObjectName, content2);
appendObjectRequest.setPosition(position);
/* 第二次追加檔案。*/
auto outcome = client.AppendObject(appendObjectRequest);
if (outcome.isSuccess()) {
std::cout << "versionid:" << outcome.result().VersionId() << std::endl;
}
else {
/* 異常處理。*/
std::cout << "AppendObject fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* 釋放網路等資源。*/
ShutdownSdk();
return 0;
}
分區上傳
在受版本控制的Bucket中,調用CompleteMultipartUpload介面來完成整個檔案的分區上傳,OSS會為整個檔案產生唯一的版本ID,並在響應header中以x-oss-version-id的形式返回。
以下代碼用於分區上傳:
#include <alibabacloud/oss/OssClient.h>
#include <fstream>
int64_t getFileSize(const std::string& file)
{
std::fstream f(file, std::ios::in | std::ios::binary);
f.seekg(0, f.end);
int64_t size = f.tellg();
f.close();
return size;
}
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名稱,例如examplebucket。*/
std::string BucketName = "examplebucket";
/* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
std::string ObjectName = "exampledir/exampleobject.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);
InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
/* 初始化分區上傳事件。*/
auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
auto uploadId = uploadIdResult.result().UploadId();
std::string fileToUpload = "yourLocalFilename";
int64_t partSize = 100 * 1024;
PartList partETagList;
auto fileSize = getFileSize(fileToUpload);
int partCount = static_cast<int>(fileSize / partSize);
/* 計算分區個數。*/
if (fileSize % partSize != 0) {
partCount++;
}
/* 對每一個分區進行上傳。*/
for (int i = 1; i <= partCount; i++) {
auto skipBytes = partSize * (i - 1);
auto size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(fileToUpload, std::ios::in|std::ios::binary);
content->seekg(skipBytes, std::ios::beg);
UploadPartRequest uploadPartRequest(BucketName, ObjectName, content);
uploadPartRequest.setContentLength(size);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setPartNumber(i);
auto uploadPartOutcome = client.UploadPart(uploadPartRequest);
if (uploadPartOutcome.isSuccess()) {
Part part(i, uploadPartOutcome.result().ETag());
partETagList.push_back(part);
}
else {
std::cout << "uploadPart fail" <<
",code:" << uploadPartOutcome.error().Code() <<
",message:" << uploadPartOutcome.error().Message() <<
",requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
}
}
/* 完成分區上傳。*/
CompleteMultipartUploadRequest request(BucketName, ObjectName);
request.setUploadId(uploadId);
request.setPartList(partETagList);
auto outcome = client.CompleteMultipartUpload(request);
if (outcome.isSuccess()) {
std::cout << "versionid:" << outcome.result().VersionId() << std::endl;
}
else {
/* 異常處理。*/
std::cout << "CompleteMultipartUpload fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* 釋放網路等資源。*/
ShutdownSdk();
return 0;
}
相關文檔
關於簡單上傳的更多資訊,請參見PutObject。
關於追加上傳的更多資訊,請參見AppendObject。
關於分區上傳的更多資訊,請參見CompleteMultipartUpload。