项目需求
COS是完全兼容AWS S3的,项目中经常遇到客户直接使用AWS S3的相关SDK,来访问COS。
本文基于客户使用AWS SDK CPP的需求,讲述如何来用其S3的SDK访问COS。
安装AWS SDK的依赖
以CentOS 8为例,安装如下依赖包:
代码语言:javascript复制# yum install -y gcc-c cmake zlib-devel openssl-devel curl-devel
编译AWS SDK
Clone AWS SDK CPP,如下:
代码语言:javascript复制# git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp
创建编译目录,执行cmake:
代码语言:javascript复制# mkdir build_dir
# cd build_dir
# cmake -DCMAKE_BUILD_TYPE=Release ../aws-sdk-cpp
只编译安装S3相关的SDK:
代码语言:javascript复制# make -j `nproc` -C aws-cpp-sdk-core
# make -j `nproc` -C aws-cpp-sdk-s3-crt
# make -j `nproc` -C crt/aws-crt-cpp
# make -j `nproc` -C aws-cpp-sdk-s3
# make install -C aws-cpp-sdk-core
# make install -C aws-cpp-sdk-s3-crt
# make install -C crt/aws-crt-cpp
# make install -C aws-cpp-sdk-s3
验证AWS SDK访问COS
示例代码
下面以简单的GetObject为例,讲述如何初始化 S3Client,如何调用GetObject获取COS里的对象。
文件为:s3getobject.cpp,代码如下:
代码语言:javascript复制#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <unistd.h>
#include <aws/s3/S3Client.h>
#include <aws/core/Aws.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
using namespace Aws::S3;
using namespace Aws::S3::Model;
using namespace std;
bool get_s3_object(const S3Client &s3_client,
const Aws::String& s3_bucket_name,
const Aws::String& s3_object_name,
const string& file_name)
{
GetObjectRequest object_request;
object_request.SetBucket(s3_bucket_name);
object_request.SetKey(s3_object_name);
time_t time1 = time(nullptr);
Aws::S3::Model::GetObjectOutcome outcome = s3_client.GetObject(object_request);
if(!outcome.IsSuccess()) {
cout << "GetObject error: " <<
outcome.GetError().GetExceptionName() << " - " <<
outcome.GetError().GetMessage() << endl;
return -1;
}
time_t time2 = time(nullptr);
Aws::OFStream local_file;
local_file.open(file_name.c_str(), std::fstream::in | std::fstream::out | std::fstream::trunc);
assert(local_file.good());
Aws::S3::Model::GetObjectResult read_result = outcome.GetResultWithOwnership();
time_t time3 = time(nullptr);
local_file << read_result.GetBody().rdbuf();
//local_file << outcome.GetResult().GetBody().rdbuf();
local_file.close();
time_t time4 = time(nullptr);
double time_diff = difftime(time4, time1);
cout << "start getobject: " << ctime(&time1)<< endl;
cout << "done getobject: " << ctime(&time2)<< endl;
cout << "start writefile: " << ctime(&time3)<< endl;
cout << "done writefile: " << ctime(&time4)<< endl;
cout << "time_diff: " << time_diff << "s" << endl;
return true;
}
int main(int argc, char** argv)
{
if (argc < 2)
{
cout << "getobject <loops>" << endl;
exit(1);
}
int loops = atoi(argv[1]);
Aws::SDKOptions options;
Aws::InitAPI(options);
{
Aws::Client::ClientConfiguration cfg;
cfg.scheme = Aws::Http::Scheme::HTTP;
cfg.region = "ap-shanghai";
cfg.endpointOverride = "cos.ap-shanghai.myzijiebao.com";
//cfg.verifySSL = false;
//cfg.connectTimeoutMs = 100000;
//cfg.requestTimeoutMs = 100000;
Aws::Auth::AWSCredentials cred("xxxxxxxxxx", "xxxxxxxxxx");
S3Client s3_client(cred, cfg);
const Aws::String bucket_name = "bruins-1253766168";
const string file_name = "localfile";
const Aws::String object_name = "testfile";
cout << "从存储桶 " << bucket_name
<< "下载对象 " << object_name
<< "存为 " << file_name << endl;
for (int i = 1; i <= loops; i) {
cout << "loop-" << i << endl;
get_s3_object(s3_client, bucket_name, object_name, file_name);
}
}
Aws::ShutdownAPI(options);
}
编译运行
AWS SDK CPP默认编译安装的目录为:/usr/local/lib64,所以在下面编译时要指定该PATH。
代码语言:javascript复制编译命令如下:
# g -std=c 11 -I/usr/local/include -L/usr/local/lib64 -laws-cpp-sdk-core -laws-cpp-sdk-s3 s3getobject.cpp -o s3getobject
运行如下:
# export LD_LIBRARY_PATH=/usr/local/lib64
# ./s3getobject