拉取minio
docker pull minio/minio
创建minio容器
docker run -p 9000:9000 -p 9001:9001 --name minio -e "MINIO_ROOT_USER=hongyaohongyao" -e "MINIO_ROOT_PASSWORD=hongyaohongyao123" -v /d/cache/docker/minio/data:/data -d minio/minio server /data --console-address ":9001"
MINIO_ROOT_USER也对应后面MinioClient初始化参数中的accessKey
MINIO_ROOT_PASSWORD对应secretKey
/d/表示D盘,即D://,docker的语法。
因为个人的项目只需要在内存中操作数据,所以暂不支持本地文件的上传下载,有需要可以自己实现,思路差不多。
里面还加了直接上传opencv图像的方法,如果不需要可以删掉。
#ifndef S3_UTILS_HPP
#define S3_UTILS_HPP
#include <string>
#include <opencv2/opencv.hpp>
#include <aws/s3/S3Client.h>
#include <aws/core/Aws.h>
namespace s3_utils {
void initAwsAPI(bool shutdown = false);
class MinioClient {
std::shared_ptr<Aws::S3::S3Client> client_;
public:
MinioClient(const std::string &endpoint, const std::string &accessKey, const std::string &secretKey);
~MinioClient() {
client_.reset();
}
bool
upload(const cv::Mat &img, const std::string &bucketName,
const std::string &objectKey, const std::vector<int> &vecCompression_params = {});
bool upload(const std::string &contents, const std::string &bucketName,
const std::string &objectKey);
std::string download(const std::string &bucketName, const std::string &objectKey);
cv::Mat downloadImg(const std::string &bucketName, const std::string &objectKey);
};
}
#endif //S3_UTILS_HPP
#include <common/ilogger.hpp> 提供的INFO方法,可以自己换成其他的logger
注意Aws::InitAPI和Aws::ShutdownAPI是全局的,影响的是整个程序,所以启动和关闭都在整个程序中都只需要一次。之前没理解以为是一个Aws::SDKOptions控制一个,init和shutdown了多次,结果程序就崩了嵐。
#include "common/s3_utils.hpp"
#include "aws\core\auth\AWSCredentialsProvider.h"
#include "aws\s3\model\PutObjectRequest.h"
#include "aws\s3\model\GetObjectRequest.h"
#include <common/ilogger.hpp>
#undef GetObject
#undef GetMessage
void s3_utils::initAwsAPI(bool shutdown) {
static bool isInited = false;
static Aws::SDKOptions options;
if (not isInited && not shutdown) {
Aws::InitAPI(options);
isInited = true;
} else if (isInited && shutdown) {
Aws::ShutdownAPI(options);
isInited = false;
}
}
s3_utils::MinioClient::MinioClient(const std::string &endpoint, const std::string &accessKey,
const std::string &secretKey) {
initAwsAPI();
Aws::Client::ClientConfiguration cfg;
cfg.endpointOverride = endpoint; // S3服务器地址和端口
INFO("endpoint %s access_key %s secret_key %s", endpoint.c_str(), accessKey.c_str(), secretKey.c_str());
cfg.scheme = Aws::Http::Scheme::HTTP;
cfg.verifySSL = false;
client_ = std::make_shared<Aws::S3::S3Client>(Aws::Auth::AWSCredentials(accessKey, secretKey), cfg,
Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, false);
}
bool s3_utils::MinioClient::upload(const cv::Mat &img,
const std::string &bucketName,
const std::string &objectKey, const std::vector<int> &vecCompression_params) {
std::vector<uchar> vec_Img;
imencode(".jpg", img, vec_Img, vecCompression_params);
Aws::S3::Model::PutObjectRequest putObjectRequest;
putObjectRequest.WithBucket(bucketName).WithKey(objectKey);
auto img_stream = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream");
img_stream->write((char *) vec_Img.data(), (long long) vec_Img.size());
putObjectRequest.SetBody(img_stream);
auto putObjectResult = client_->PutObject(putObjectRequest);
if (not putObjectResult.IsSuccess()) {
INFO(putObjectResult.GetError().GetMessage().c_str());
return false;
}
return true;
}
bool s3_utils::MinioClient::upload(const std::string &contents, const std::string &bucketName,
const std::string &objectKey) {
Aws::S3::Model::PutObjectRequest putObjectRequest;
putObjectRequest.WithBucket(bucketName).WithKey(objectKey);
auto contents_stream = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream", contents);
putObjectRequest.SetBody(contents_stream);
auto putObjectResult = client_->PutObject(putObjectRequest);
if (not putObjectResult.IsSuccess()) {
INFO(putObjectResult.GetError().GetMessage().c_str());
return false;
}
return true;
}
std::string s3_utils::MinioClient::download(const std::string &bucketName, const std::string &objectKey) {
INFO("bucket: %s dir: %s", bucketName.c_str(), objectKey.c_str());
Aws::S3::Model::GetObjectRequest object_request;
object_request.WithBucket(bucketName).WithKey(objectKey);
auto get_object_outcome = client_->GetObject(object_request);
if (get_object_outcome.IsSuccess()) {
std::ostringstream tmp;
tmp << get_object_outcome.GetResult().GetBody().rdbuf();
return tmp.str();
} else {
INFO(get_object_outcome.GetError().GetMessage().c_str());
return "";
}
}
cv::Mat s3_utils::MinioClient::downloadImg(const std::string &bucketName, const std::string &objectKey) {
INFO("downloading img bucket: %s dir: %s", bucketName.c_str(), objectKey.c_str());
Aws::S3::Model::GetObjectRequest object_request;
object_request.WithBucket(bucketName).WithKey(objectKey);
auto get_object_outcome = client_->GetObject(object_request);
if (get_object_outcome.IsSuccess()) {
auto &body = get_object_outcome.GetResult().GetBody();
std::vector<uchar> vec_img;
vec_img.assign(Aws::IStreamBufIterator(body), Aws::IStreamBufIterator());
cv::Mat result = cv::imdecode(vec_img, cv::IMREAD_COLOR);
return result;
} else {
INFO(get_object_outcome.GetError().GetMessage().c_str());
return {};
}
}