初始化 CMakeList 导入 AWS SDK for C++
确保 CMake v3.14+
,libcurl
,OpenSSL v1.x
已经安装。
创建 CMakeLists.txt
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(aws-sdk-cpp-qiniu-example VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
include(FetchContent)
fetchcontent_declare(
awscppsdk
GIT_REPOSITORY https://github.com/aws/aws-sdk-cpp.git
GIT_PROGRESS TRUE
GIT_SUBMODULES crt/aws-crt-cpp
GIT_TAG 1.11.166
)
if(NOT awscppsdk_POPULATED)
fetchcontent_populate(awscppsdk)
set(BUILD_ONLY "s3;transfer;sts")
set(ENABLE_TESTING OFF)
fetchcontent_makeavailable(awscppsdk)
add_subdirectory(${awscppsdk_SOURCE_DIR} ${awscppsdk_BUILD_DIR})
endif()
aux_source_directory(src SRCS)
add_executable(${PROJECT_NAME} ${SRCS})
if(MSVC AND BUILD_SHARED_LIBS)
target_compile_definitions(${PROJECT_NAME} PUBLIC "USE_IMPORT_EXPORT")
add_definitions(-DUSE_IMPORT_EXPORT)
list(APPEND SERVICE_LIST s3)
AWSSDK_CPY_DYN_LIBS(SERVICE_LIST "" ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
endif()
set_compiler_flags(${PROJECT_NAME})
set_compiler_warnings(${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} aws-cpp-sdk-core aws-cpp-sdk-s3 aws-cpp-sdk-transfer aws-cpp-sdk-sts)
对于之后的每个代码示例,将代码创建在 src/main.cpp
后,执行
cmake -S . -B build
cmake --build build --config Debug
即可编译出可执行文件。
对象上传
获取客户端上传 URL
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::String url = s3Client.GeneratePresignedUrl("<Bucket>", "<ObjectName>", Aws::Http::HttpMethod::HTTP_PUT);
std::cout << url << std::endl;
}
Aws::ShutdownAPI(options);
return 0;
}
这段代码将生成一个经过预先签名的客户端上传 URL,有效期为 7 天,客户端可以在有效时间内对该 URL 发送 HTTP PUT 请求将文件上传。
以下是用 curl 上传文件的案例:
curl -X PUT --upload-file "<path/to/file>" "<presigned url>"
您也可以自行指定上传凭证的有效期,例如:
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::String url = s3Client.GeneratePresignedUrl("<Bucket>", "<ObjectName>", Aws::Http::HttpMethod::HTTP_PUT, 3600); // 有效期为一小时
std::cout << url << std::endl;
}
Aws::ShutdownAPI(options);
return 0;
}
服务器端直传
单请求上传(文件)
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <iostream>
#include <fstream>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<AccessKey>", "<SecretKey>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::PutObjectRequest putObjectRequest;
putObjectRequest.SetBucket("<Bucket>");
putObjectRequest.SetKey("<Key>");
std::shared_ptr<Aws::IOStream> requestBody = Aws::MakeShared<Aws::FStream>("PutObjectAllocationTag", "<path/to/upload>", std::ios_base::in | std::ios_base::binary);
if (!*requestBody)
{
std::cerr << "Error: open file: " << strerror(errno) << std::endl;
goto fail;
}
putObjectRequest.SetBody(requestBody);
Aws::S3::Model::PutObjectOutcome putObjectOutcome = s3Client.PutObject(putObjectRequest);
if (!putObjectOutcome.IsSuccess())
{
std::cerr << "Error: PutObject: " << putObjectOutcome.GetError().GetMessage() << std::endl; // 上传错误,输出错误信息
}
else
{
std::cout << "ETag: " << putObjectOutcome.GetResult().GetETag() << std::endl; // 上传成功,打印 ETag
}
}
fail:
Aws::ShutdownAPI(options);
return 0;
}
单请求上传(数据流)
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <iostream>
#include <fstream>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<AccessKey>", "<SecretKey>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::PutObjectRequest putObjectRequest;
putObjectRequest.SetBucket("<Bucket>");
putObjectRequest.SetKey("<Key>");
std::shared_ptr<Aws::IOStream> requestBody = Aws::MakeShared<Aws::StringStream>(""); // 这里用 Aws::StringStream 来模拟 Aws::IOStream 实例
*requestBody << "Hello Qiniu S3!";
putObjectRequest.SetBody(requestBody);
Aws::S3::Model::PutObjectOutcome putObjectOutcome = s3Client.PutObject(putObjectRequest);
if (!putObjectOutcome.IsSuccess())
{
std::cerr << "Error: PutObject: " << putObjectOutcome.GetError().GetMessage() << std::endl; // 上传错误,输出错误信息
}
else
{
std::cout << "ETag: " << putObjectOutcome.GetResult().GetETag() << std::endl; // 上传成功,打印 ETag
}
}
Aws::ShutdownAPI(options);
return 0;
}
分片上传(文件)
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/CompletedPart.h>
#include <aws/s3/model/CompleteMultipartUploadRequest.h>
#include <aws/s3/model/CreateMultipartUploadRequest.h>
#include <aws/s3/model/UploadPartRequest.h>
#include <fstream>
#include <sstream>
#include <string>
static std::size_t read_bytes(std::istream &in, char *buf, std::size_t len)
{
std::size_t n = 0;
while (len > 0 && in.good())
{
in.read(&buf[n], len);
int i = in.gcount();
n += i;
len -= i;
}
return n;
}
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<AccessKey>", "<SecretKey>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
std::shared_ptr<Aws::IOStream> file = Aws::MakeShared<Aws::FStream>("PutObjectAllocationTag", "<path/to/upload>", std::ios_base::in | std::ios_base::binary);
if (!*file)
{
std::cerr << "Error: open file: " << strerror(errno) << std::endl;
goto fail;
}
Aws::S3::Model::CreateMultipartUploadRequest createMultipartUploadRequest;
createMultipartUploadRequest.SetBucket("<Bucket>");
createMultipartUploadRequest.SetKey("<Key>");
Aws::S3::Model::CreateMultipartUploadOutcome createMultipartUploadOutcome = s3Client.CreateMultipartUpload(createMultipartUploadRequest);
if (!createMultipartUploadOutcome.IsSuccess())
{
std::cerr << "CreateMultipartUpload Error:" << createMultipartUploadOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
const long long PART_SIZE = 5 * 1024 * 1024; // 分片大小为 5 MB
long long partSize = PART_SIZE;
Aws::Vector<Aws::S3::Model::CompletedPart> parts;
// 这里给出的案例是串行分片上传。可以自行改造成并行分片上传以进一步提升上传速度
for (long long uploaded = 0, partNumber = 1;; uploaded += partSize, partNumber++)
{
std::vector<char> bytes(partSize);
std::size_t haveRead = read_bytes(*file, bytes.data(), partSize);
if (haveRead == 0)
{
break;
}
Aws::S3::Model::UploadPartRequest uploadPartRequest;
uploadPartRequest.SetUploadId(createMultipartUploadOutcome.GetResult().GetUploadId());
uploadPartRequest.SetPartNumber(partNumber);
uploadPartRequest.SetBucket(createMultipartUploadRequest.GetBucket());
uploadPartRequest.SetKey(createMultipartUploadRequest.GetKey());
uploadPartRequest.SetBody(Aws::MakeShared<Aws::StringStream>("UploadPartAllocationTag", std::string(bytes.data(), haveRead)));
Aws::S3::Model::UploadPartOutcome uploadPartOutcome = s3Client.UploadPart(uploadPartRequest);
if (!uploadPartOutcome.IsSuccess())
{
std::cerr << "UploadPart Error:" << uploadPartOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
Aws::S3::Model::CompletedPart completedPart;
completedPart.SetETag(uploadPartOutcome.GetResult().GetETag());
completedPart.SetPartNumber(partNumber);
parts.push_back(completedPart);
}
Aws::S3::Model::CompletedMultipartUpload completedMultipartUpload;
completedMultipartUpload.SetParts(parts);
Aws::S3::Model::CompleteMultipartUploadRequest completeMultipartUploadRequest;
completeMultipartUploadRequest.SetBucket(createMultipartUploadRequest.GetBucket());
completeMultipartUploadRequest.SetKey(createMultipartUploadRequest.GetKey());
completeMultipartUploadRequest.SetUploadId(createMultipartUploadOutcome.GetResult().GetUploadId());
completeMultipartUploadRequest.SetMultipartUpload(completedMultipartUpload);
Aws::S3::Model::CompleteMultipartUploadOutcome completeMultipartUploadOutcome = s3Client.CompleteMultipartUpload(completeMultipartUploadRequest);
if (!completeMultipartUploadOutcome.IsSuccess())
{
std::cerr << "CompleteMultipartUpload Error:" << completeMultipartUploadOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
std::cout << "Etag: " << completeMultipartUploadOutcome.GetResult().GetETag() << std::endl; // 复制成功
}
fail:
Aws::ShutdownAPI(options);
return 0;
}
上传文件
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/transfer/TransferManager.h>
#include <iostream>
#include <fstream>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<AccessKey>", "<SecretKey>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
std::shared_ptr<Aws::S3::S3Client> s3Client = Aws::MakeShared<Aws::S3::S3Client>("S3Client", credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
std::shared_ptr<Aws::Utils::Threading::Executor> executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 5);
Aws::Transfer::TransferManagerConfiguration transferConfig(executor.get());
transferConfig.s3Client = s3Client;
std::shared_ptr<Aws::Transfer::TransferManager> transferManager = Aws::Transfer::TransferManager::Create(transferConfig);
std::shared_ptr<Aws::IOStream> requestBody = Aws::MakeShared<Aws::FStream>("PutObjectAllocationTag", "<path/to/upload>", std::ios_base::in | std::ios_base::binary);
if (!*requestBody)
{
std::cerr << "Error: open file: " << strerror(errno) << std::endl;
goto fail;
}
std::shared_ptr<Aws::Transfer::TransferHandle> uploadHandle = transferManager->UploadFile(requestBody, "<Bucket>", "<Key>", "<ContentType>", Aws::Map<Aws::String, Aws::String>());
uploadHandle->WaitUntilFinished();
if (uploadHandle->GetStatus() != Aws::Transfer::TransferStatus::COMPLETED)
{
std::cerr << "Error: TransferManager: " << uploadHandle->GetLastError().GetMessage() << std::endl;
}
else
{
std::cout << "Size: " << uploadHandle->GetBytesTotalSize() << std::endl;
}
}
Aws::ShutdownAPI(options);
return 0;
}
上传目录
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/transfer/TransferManager.h>
#include <iostream>
#include <fstream>
int main()
{
Aws::SDKOptions options;
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<AccessKey>", "<SecretKey>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
std::shared_ptr<Aws::S3::S3Client> s3Client = Aws::MakeShared<Aws::S3::S3Client>("S3Client", credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
std::shared_ptr<Aws::Utils::Threading::Executor> executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 5);
Aws::Transfer::TransferManagerConfiguration transferConfig(executor.get());
transferConfig.s3Client = s3Client;
transferConfig.transferInitiatedCallback = [](const Aws::Transfer::TransferManager *, const std::shared_ptr<const Aws::Transfer::TransferHandle> &) {};
transferConfig.errorCallback = [](const Aws::Transfer::TransferManager *, const std::shared_ptr<const Aws::Transfer::TransferHandle> &handle, const Aws::Client::AWSError<Aws::S3::S3Errors> &error)
{
std::cout << "Error: " << handle->GetBucketName() << "/" << handle->GetKey() << ": " << error.GetMessage() << std::endl;
};
std::shared_ptr<Aws::Transfer::TransferManager> transferManager = Aws::Transfer::TransferManager::Create(transferConfig);
transferManager->UploadDirectory("<path/to/upload>", "<Bucket>", "<KeyPrefix>", Aws::Http::HeaderValueCollection());
Aws::Transfer::TransferStatus status = transferManager->WaitUntilAllFinished();
if (status == Aws::Transfer::TransferStatus::COMPLETED)
{
std::cout << "Done" << std::endl;
}
else
{
std::cerr << "Error: " << status << std::endl;
}
}
Aws::ShutdownAPI(options);
return 0;
}
对象下载
获取客户端下载 URL
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::String url = s3Client.GeneratePresignedUrl("<Bucket>", "<ObjectName>", Aws::Http::HttpMethod::HTTP_GET);
std::cout << url << std::endl;
}
Aws::ShutdownAPI(options);
return 0;
}
这段代码将生成一个经过预先签名的客户端下载 URL,有效期为 7 天,客户端可以在有效时间内对该 URL 发送 HTTP GET 请求将文件下载。
以下是用 curl 下载文件的案例:
curl -o "<path/to/download>" "<presigned url>"
您也可以自行指定下载凭证的有效期,例如:
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::String url = s3Client.GeneratePresignedUrl("<Bucket>", "<Key>", Aws::Http::HttpMethod::HTTP_GET, 3600); // 有效期为一小时
std::cout << url << std::endl;
}
Aws::ShutdownAPI(options);
return 0;
}
服务器端直接下载
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <fstream>
static std::streamsize copy(std::istream &in, std::ostream &out)
{
std::vector<char> bytes(32 * 1024);
std::streamsize have_copied = 0;
while (in.good() && out.good())
{
in.read(bytes.data(), bytes.size());
std::streamsize have_read = in.gcount();
have_copied += have_read;
out.write(bytes.data(), have_read);
}
return have_copied;
}
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
std::shared_ptr<Aws::IOStream> file = Aws::MakeShared<Aws::FStream>("GetObjectAllocationTag", "<path/to/download>", std::ios_base::out | std::ios_base::binary);
if (!*file)
{
std::cerr << "Error: open file: " << strerror(errno) << std::endl;
goto fail;
}
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::GetObjectRequest getObjectRequest;
getObjectRequest.SetBucket("<Bucket>");
getObjectRequest.SetKey("<Key>");
Aws::S3::Model::GetObjectOutcome getObjectOutcome = s3Client.GetObject(getObjectRequest);
if (!getObjectOutcome.IsSuccess())
{
std::cerr << "Error: GetObject: " << getObjectOutcome.GetError().GetMessage() << std::endl; // 下载错误,输出错误信息
}
else
{
copy(getObjectOutcome.GetResult().GetBody(), *file);
std::cout << "ETag: " << getObjectOutcome.GetResult().GetETag() << std::endl; // 下载成功,打印 ETag
}
}
fail:
Aws::ShutdownAPI(options);
return 0;
}
下载文件
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/transfer/TransferManager.h>
#include <iostream>
#include <fstream>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<AccessKey>", "<SecretKey>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
std::shared_ptr<Aws::S3::S3Client> s3Client = Aws::MakeShared<Aws::S3::S3Client>("S3Client", credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
std::shared_ptr<Aws::Utils::Threading::Executor> executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 5);
Aws::Transfer::TransferManagerConfiguration transferConfig(executor.get());
transferConfig.s3Client = s3Client;
std::shared_ptr<Aws::Transfer::TransferManager> transferManager = Aws::Transfer::TransferManager::Create(transferConfig);
std::shared_ptr<Aws::Transfer::TransferHandle> downloadHandle = transferManager->DownloadFile("<Bucket>", "<Key>", "<path/to/download>");
downloadHandle->WaitUntilFinished();
if (downloadHandle->GetStatus() != Aws::Transfer::TransferStatus::COMPLETED)
{
std::cerr << "Error: TransferManager: " << downloadHandle->GetLastError().GetMessage() << std::endl;
}
else
{
std::cout << "Size: " << downloadHandle->GetBytesTotalSize() << std::endl;
}
}
Aws::ShutdownAPI(options);
return 0;
}
下载目录
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/transfer/TransferManager.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
std::shared_ptr<Aws::S3::S3Client> s3Client = Aws::MakeShared<Aws::S3::S3Client>("S3Client", credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
std::shared_ptr<Aws::Utils::Threading::Executor> executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 5);
Aws::Transfer::TransferManagerConfiguration transferConfig(executor.get());
transferConfig.s3Client = s3Client;
transferConfig.transferInitiatedCallback = [](const Aws::Transfer::TransferManager *, const std::shared_ptr<const Aws::Transfer::TransferHandle> &) {};
transferConfig.errorCallback = [](const Aws::Transfer::TransferManager *, const std::shared_ptr<const Aws::Transfer::TransferHandle> &handle, const Aws::Client::AWSError<Aws::S3::S3Errors> &error)
{
std::cout << "Error: " << handle->GetBucketName() << "/" << handle->GetKey() << ": " << error.GetMessage() << std::endl;
};
std::shared_ptr<Aws::Transfer::TransferManager> transferManager = Aws::Transfer::TransferManager::Create(transferConfig);
transferManager->DownloadToDirectory("<path/to/download>", "<Bucket>", "<KeyPrefix>");
Aws::Transfer::TransferStatus status = transferManager->WaitUntilAllFinished();
if (status == Aws::Transfer::TransferStatus::COMPLETED)
{
std::cout << "Done" << std::endl;
}
else
{
std::cerr << "Error" << std::endl;
}
}
Aws::ShutdownAPI(options);
return 0;
}
对象管理
获取对象信息
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/HeadObjectRequest.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::HeadObjectRequest headObjectRequest;
headObjectRequest.SetBucket("<Bucket>");
headObjectRequest.SetKey("<Key>");
Aws::S3::Model::HeadObjectOutcome headObjectOutcome = s3Client.HeadObject(headObjectRequest);
if (!headObjectOutcome.IsSuccess())
{
std::cerr << "Error: HeadObject: " << headObjectOutcome.GetError().GetMessage() << std::endl; // 下载错误,输出错误信息
}
else
{
std::cout << "ETag: " << headObjectOutcome.GetResult().GetETag() << std::endl; // 获取成功,打印 ETag
}
}
Aws::ShutdownAPI(options);
return 0;
}
修改对象 MimeType
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/CopyObjectRequest.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::CopyObjectRequest copyObjectRequest;
copyObjectRequest.SetBucket("<Bucket>");
copyObjectRequest.SetKey("<Key>");
copyObjectRequest.SetCopySource("/<Bucket>/<Key>");
copyObjectRequest.SetMetadataDirective(Aws::S3::Model::MetadataDirective::REPLACE);
copyObjectRequest.SetContentType("<NewContentType>");
Aws::S3::Model::CopyObjectOutcome copyObjectOutcome = s3Client.CopyObject(copyObjectRequest);
if (!copyObjectOutcome.IsSuccess())
{
std::cerr << "Error: CopyObject: " << copyObjectOutcome.GetError().GetMessage() << std::endl; // 修改错误,输出错误信息
}
else
{
std::cout << "Done" << std::endl; // 修改成功
}
}
Aws::ShutdownAPI(options);
return 0;
}
修改对象存储类型
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/CopyObjectRequest.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::CopyObjectRequest copyObjectRequest;
copyObjectRequest.SetBucket("<Bucket>");
copyObjectRequest.SetKey("<Key>");
copyObjectRequest.SetCopySource("/<Bucket>/<Key>");
copyObjectRequest.SetMetadataDirective(Aws::S3::Model::MetadataDirective::COPY);
copyObjectRequest.SetStorageClass(Aws::S3::Model::StorageClass::GLACIER);
Aws::S3::Model::CopyObjectOutcome copyObjectOutcome = s3Client.CopyObject(copyObjectRequest);
if (!copyObjectOutcome.IsSuccess())
{
std::cerr << "Error: CopyObject: " << copyObjectOutcome.GetError().GetMessage() << std::endl; // 修改错误,输出错误信息
}
else
{
std::cout << "Done" << std::endl; // 修改成功
}
}
Aws::ShutdownAPI(options);
return 0;
}
复制对象副本
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/CopyObjectRequest.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::CopyObjectRequest copyObjectRequest;
copyObjectRequest.SetBucket("<ToBucket>");
copyObjectRequest.SetKey("<ToKey>");
copyObjectRequest.SetCopySource("/<FromBucket>/<FromKey>");
copyObjectRequest.SetMetadataDirective(Aws::S3::Model::MetadataDirective::COPY);
Aws::S3::Model::CopyObjectOutcome copyObjectOutcome = s3Client.CopyObject(copyObjectRequest);
if (!copyObjectOutcome.IsSuccess())
{
std::cerr << "Error: CopyObject: " << copyObjectOutcome.GetError().GetMessage() << std::endl; // 修改错误,输出错误信息
}
else
{
std::cout << "Done" << std::endl; // 修改成功
}
}
Aws::ShutdownAPI(options);
return 0;
}
复制对象副本(大于 5GB)
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/CompletedPart.h>
#include <aws/s3/model/CompleteMultipartUploadRequest.h>
#include <aws/s3/model/CreateMultipartUploadRequest.h>
#include <aws/s3/model/HeadObjectRequest.h>
#include <aws/s3/model/UploadPartCopyRequest.h>
#include <algorithm>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::HeadObjectRequest headObjectRequest;
headObjectRequest.SetBucket("<FromBucket>");
headObjectRequest.SetKey("<FromKey>");
Aws::S3::Model::HeadObjectOutcome headObjectOutcome = s3Client.HeadObject(headObjectRequest);
if (!headObjectOutcome.IsSuccess())
{
std::cerr << "HeadObject Error:" << headObjectOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
Aws::S3::Model::CreateMultipartUploadRequest createMultipartUploadRequest;
createMultipartUploadRequest.SetBucket("<ToBucket>");
createMultipartUploadRequest.SetKey("<ToKey>");
Aws::S3::Model::CreateMultipartUploadOutcome createMultipartUploadOutcome = s3Client.CreateMultipartUpload(createMultipartUploadRequest);
if (!createMultipartUploadOutcome.IsSuccess())
{
std::cerr << "CreateMultipartUpload Error:" << createMultipartUploadOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
const long long PART_SIZE = 5 * 1024 * 1024; // 分片大小,调整过小会影响复制速度,调整过大可能导致服务器超时
long long partSize = PART_SIZE;
Aws::Vector<Aws::S3::Model::CompletedPart> parts;
// 这里给出的案例是串行分片复制。可以自行改造成并行分片复制以进一步提升复制速度
for (long long copied = 0, partNumber = 1; copied < headObjectOutcome.GetResult().GetContentLength(); copied += partSize, partNumber++)
{
partSize = std::min(headObjectOutcome.GetResult().GetContentLength() - copied, PART_SIZE);
Aws::S3::Model::UploadPartCopyRequest uploadPartCopyRequest;
uploadPartCopyRequest.SetUploadId(createMultipartUploadOutcome.GetResult().GetUploadId());
uploadPartCopyRequest.SetPartNumber(partNumber);
uploadPartCopyRequest.SetBucket(createMultipartUploadRequest.GetBucket());
uploadPartCopyRequest.SetKey(createMultipartUploadRequest.GetKey());
Aws::String copySource = "/";
copySource.append(headObjectRequest.GetBucket()).append("/").append(headObjectRequest.GetKey());
uploadPartCopyRequest.SetCopySource(copySource);
Aws::String copySourceRange = "bytes=";
copySourceRange.append(std::to_string(copied));
copySourceRange.append("-");
copySourceRange.append(std::to_string(copied + partSize - 1));
uploadPartCopyRequest.SetCopySourceRange(copySourceRange);
Aws::S3::Model::UploadPartCopyOutcome uploadPartCopyOutcome = s3Client.UploadPartCopy(uploadPartCopyRequest);
if (!uploadPartCopyOutcome.IsSuccess())
{
std::cerr << "UploadPartCopy Error:" << uploadPartCopyOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
Aws::S3::Model::CompletedPart completedPart;
completedPart.SetETag(uploadPartCopyOutcome.GetResult().GetCopyPartResult().GetETag());
completedPart.SetPartNumber(partNumber);
parts.push_back(completedPart);
}
Aws::S3::Model::CompletedMultipartUpload completedMultipartUpload;
completedMultipartUpload.SetParts(parts);
Aws::S3::Model::CompleteMultipartUploadRequest completeMultipartUploadRequest;
completeMultipartUploadRequest.SetBucket(createMultipartUploadRequest.GetBucket());
completeMultipartUploadRequest.SetKey(createMultipartUploadRequest.GetKey());
completeMultipartUploadRequest.SetUploadId(createMultipartUploadOutcome.GetResult().GetUploadId());
completeMultipartUploadRequest.SetMultipartUpload(completedMultipartUpload);
Aws::S3::Model::CompleteMultipartUploadOutcome completeMultipartUploadOutcome = s3Client.CompleteMultipartUpload(completeMultipartUploadRequest);
if (!completeMultipartUploadOutcome.IsSuccess())
{
std::cerr << "CompleteMultipartUpload Error:" << completeMultipartUploadOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
std::cout << "Done" << std::endl; // 复制成功
}
fail:
Aws::ShutdownAPI(options);
return 0;
}
删除空间中的文件
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/DeleteObjectRequest.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::DeleteObjectRequest deleteObjectRequest;
deleteObjectRequest.SetBucket("<Bucket>");
deleteObjectRequest.SetKey("<Key>");
Aws::S3::Model::DeleteObjectOutcome deleteObjectOutcome = s3Client.DeleteObject(deleteObjectRequest);
if (!deleteObjectOutcome.IsSuccess())
{
std::cerr << "Error: DeleteObject: " << deleteObjectOutcome.GetError().GetMessage() << std::endl; // 删除错误,输出错误信息
}
else
{
std::cout << "Done" << std::endl; // 删除成功
}
}
Aws::ShutdownAPI(options);
return 0;
}
获取指定前缀的文件列表
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/ListObjectsV2Request.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::ListObjectsV2Request listObjectsV2Request;
listObjectsV2Request.SetBucket("<Bucket>");
listObjectsV2Request.SetPrefix("<KeyPrefix>");
Aws::S3::Model::ListObjectsV2Outcome listObjectsV2Outcome = s3Client.ListObjectsV2(listObjectsV2Request);
if (!listObjectsV2Outcome.IsSuccess())
{
std::cerr << "Error: ListObjects: " << listObjectsV2Outcome.GetError().GetMessage() << std::endl; // 列举错误,输出错误信息
}
else
{
for (const Aws::S3::Model::Object &object : listObjectsV2Outcome.GetResult().GetContents())
{
std::cout << "Key: " << object.GetKey() << std::endl;
std::cout << "ETag: " << object.GetETag() << std::endl;
}
}
}
Aws::ShutdownAPI(options);
return 0;
}
批量删除空间中的文件
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/DeleteObjectsRequest.h>
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
Aws::S3::S3Client s3Client(credential, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
Aws::S3::Model::Delete deleteRequest;
deleteRequest.AddObjects(Aws::S3::Model::ObjectIdentifier().WithKey("<Key1>"));
deleteRequest.AddObjects(Aws::S3::Model::ObjectIdentifier().WithKey("<Key2>"));
deleteRequest.AddObjects(Aws::S3::Model::ObjectIdentifier().WithKey("<Key3>"));
deleteRequest.AddObjects(Aws::S3::Model::ObjectIdentifier().WithKey("<Key4>"));
deleteRequest.AddObjects(Aws::S3::Model::ObjectIdentifier().WithKey("<Key5>"));
Aws::S3::Model::DeleteObjectsRequest deleteObjectsRequest;
deleteObjectsRequest.SetBucket("<Bucket>");
deleteObjectsRequest.SetDelete(deleteRequest);
Aws::S3::Model::DeleteObjectsOutcome deleteObjectsOutcome = s3Client.DeleteObjects(deleteObjectsRequest);
if (!deleteObjectsOutcome.IsSuccess())
{
std::cerr << "Error: DeleteObjects: " << deleteObjectsOutcome.GetError().GetMessage() << std::endl; // 删除错误,输出错误信息
}
else
{
for (const Aws::S3::Model::DeletedObject &object : deleteObjectsOutcome.GetResult().GetDeleted())
{
std::cout << "Deleted: " << object.GetKey() << std::endl;
}
for (const Aws::S3::Model::Error &error : deleteObjectsOutcome.GetResult().GetErrors())
{
std::cout << "Error: " << error.GetMessage() << std::endl;
}
}
}
Aws::ShutdownAPI(options);
return 0;
}
临时安全凭证
创建 src/main.cpp
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/s3/S3Client.h>
#include <aws/sts/STSClient.h>
#include <aws/sts/model/GetFederationTokenRequest.h>
#include <aws/crt/Optional.h>
class STSCredentialsProvider : public Aws::Auth::AWSCredentialsProvider
{
public:
STSCredentialsProvider(const Aws::Auth::AWSCredentials &credentials, const Aws::STS::STSClientConfiguration &clientConfiguration = Aws::STS::STSClientConfiguration())
: Aws::Auth::AWSCredentialsProvider(),
stsClient(credentials, Aws::MakeShared<Aws::STS::STSEndpointProvider>(Aws::STS::STSClient::ALLOCATION_TAG), clientConfiguration)
{
}
virtual ~STSCredentialsProvider() = default;
virtual Aws::Auth::AWSCredentials GetAWSCredentials() override
{
if (!credentials.has_value() || credentials->IsExpired())
{
Reload();
return *credentials;
}
else
{
return *credentials;
}
}
protected:
virtual void Reload() override
{
Aws::STS::Model::GetFederationTokenRequest getFederationTokenRequest;
getFederationTokenRequest.SetName("Bob");
getFederationTokenRequest.SetDurationSeconds(3600);
getFederationTokenRequest.SetPolicy("{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Stmt1\",\"Effect\":\"Allow\",\"Action\":[\"*\"],\"Resource\":[\"*\"]}]}");
Aws::STS::Model::GetFederationTokenOutcome getFederationTokenOutcome = stsClient.GetFederationToken(getFederationTokenRequest);
if (getFederationTokenOutcome.IsSuccess())
{
const Aws::STS::Model::Credentials stsCredentials = std::move(getFederationTokenOutcome.GetResult().GetCredentials());
credentials = Aws::Auth::AWSCredentials(stsCredentials.GetAccessKeyId(), stsCredentials.GetSecretAccessKey(), stsCredentials.GetSessionToken(), stsCredentials.GetExpiration());
Aws::Auth::AWSCredentialsProvider::Reload();
}
else
{
std::cerr << "Error: GetFederationToken: " << getFederationTokenOutcome.GetError().GetMessage() << std::endl;
}
}
private:
Aws::STS::STSClient stsClient;
Aws::Crt::Optional<Aws::Auth::AWSCredentials> credentials;
};
int main()
{
Aws::SDKOptions options;
Aws::InitAPI(options);
{
const Aws::Auth::AWSCredentials credential("<QINIU_ACCESS_KEY>", "<QINIU_SECRET_KEY>");
Aws::Client::ClientConfiguration clientConfig;
clientConfig.endpointOverride = "https://s3.cn-east-1.qiniucs.com"; // 华东-浙江区 endpoint
clientConfig.region = "cn-east-1"; // 华东-浙江区 region id
const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> stsCredentialsProvider = Aws::MakeShared<STSCredentialsProvider>("STSCredentialsProviderTag", credential, clientConfig);
const Aws::S3::S3Client s3Client(stsCredentialsProvider, Aws::MakeShared<Aws::S3::S3EndpointProvider>(Aws::S3::S3Client::ALLOCATION_TAG), clientConfig);
// 可以使用这些临时凭证调用 S3 服务
const Aws::S3::Model::ListBucketsOutcome listBucketsOutcome = s3Client.ListBuckets();
if (listBucketsOutcome.IsSuccess())
{
for (const Aws::S3::Model::Bucket bucket : listBucketsOutcome.GetResult().GetBuckets())
{
std::cout << bucket.GetName() << std::endl;
}
}
else
{
std::cerr << "ListBuckets Error:" << listBucketsOutcome.GetError().GetMessage() << std::endl;
goto fail;
}
}
fail:
Aws::ShutdownAPI(options);
return 0;
}
文档反馈
(如有产品使用问题,请 提交工单)