minio对象存储C++上传下载和流式传输-做项目必备存储方案

视频讲解及源码领取:minio对象存储C++上传下载和流式传输-做项目必备存储方案

1 MinIO 基础概念

1.1 核心概念

  • MinIO服务器: 高性能的对象存储服务器,兼容Amazon S3 API
  • 存储桶(Bucket): 存储对象的容器,类似于文件夹
  • 对象(Object): 存储在桶中的文件,可以是任意类型的数据
  • 访问密钥: 用于身份验证的密钥对(Access Key + Secret Key)

1.2 系统架构

2 minio非docker单机快速部署

2.1 下载 MinIO 二进制文件

首先,你需要从 MinIO 官方 GitHub 发布页面下载最新版本的 MinIO 二进制文件。根据你的操作系统选择合适的版本。

对于 Linux 系统,你可以使用 wget 或者 curl 命令来下载 MinIO 的二进制文件。例如,在 Linux 上你可以这样操作:

wget https://dl.min.io/server/minio/release/linux-amd64/minio --no-check-certificate

如果你使用的是 macOS 或者 Windows,请访问 MinIO 官方发布页面找到适合你系统的版本并下载。

2.2 赋予执行权限

下载完成后,你需要为下载的 MinIO 二进制文件添加执行权限。在 Linux 或 macOS 上,你可以通过以下命令实现:

chmod +x mini

2.3 设置环境变量(可选)

为了增强安全性,建议设置 MINIO_ROOT_USER 和 MINIO_ROOT_PASSWORD 这两个环境变量来指定 MinIO 的 root 用户和密码。如果不设置,默认会生成随机凭证,这将使得登录变得困难。

在 Linux 或 macOS 中,你可以通过如下命令设置环境变量:

export MINIO_ROOT_USER='minioadmin'
export MINIO_ROOT_PASSWORD='minioadmin'

请确保替换 'minioadmin' 和 'minioadmin' 为你自己的用户名和密码。

2.4 启动 MinIO 服务器

现在,你可以通过运行以下命令启动 MinIO 服务器:

mkdir data
./minio server ./data

在这个命令中, /data 是你希望 MinIO 存储数据的目录路径。你可以根据需要更改这个路径。确保该目录存在并且有适当的读写权限。

启动后,你会看到类似如下的输出,其中包含了访问 MinIO 控制台的 URL、Access Key 和 Secret Key:

Endpoint: http://192.168.80.128:9000 http://127.0.0.1:9000
AccessKey: YOUR-ACCESSKEYHERE SecretKey: YOUR-SECRETKEYHERE
Browser Access:
    http://192.168.80.128:9000 http://127.0.0.1:9000

完整打印:

2.5 访问 MinIO 控制台

打开浏览器,输入提供的 URL(通常是 http://<your-machine-ip>:9000 ,比如我现在是http://192.168. 80.128:9000),然后使用提供的 Access Key 和 Secret Key 登录 MinIO 控制台。

3 C++ SDK上传和下载文件

3.1 官方C++ sdk安装

需要依赖vcpkg

# 下载vcpkg
git clone https://github.com/microsoft/vcpkg.git
# 进入vcpkg
cd vcpkg
./bootstrap-vcpkg.sh

# 安装minio-cpp,时间有点久,耐心等待
./vcpkg install minio-cpp

3.2 编译范例

以cmake方式构建的范例工程

mkdir build && cd build
cmake ..
make

3.3 执行程序

3.3.1 minio_basic文件上传下载

# 将源码目录的test-file.txt拷贝到build目录
lqf@ubuntu:~/minio/app/build$ cp ../test-file.txt .
lqf@ubuntu:~/minio/app/build$ ./minio_basic

执行成功打印:

开始上传文件到MinIO...
文件上传成功, ETag:
存储位置: video/test-file.txt

=== 上传响应详细信息 ===
状态码: 0
ETag: d249d192f7ab36c408f21125c2bc44d0
版本ID: 无
请求ID: 无
主机ID: 无
开始从MinIO下载文件...
文件下载成功!
保存位置: ./downloaded-file.txt
程序执行完成!

下载的内容保存为downloaded-file.txt。

3.3.2 minio_stream文件流式上传

# 将源码目录的time.flv拷贝到build目录
lqf@ubuntu:~/minio/app/build$ cp ../time.flv .
lqf@ubuntu:~/minio/app/build$ ./minio_stream time.flv

执行成功打印:

=== 开始模拟web上传流式传输 ===
源文件: time.flv
目标位置: video/time.flv
每次读取: 32768 字节 (32KB)
文件总大小: 20184976 字节 (19711KB)

文件大于等于5MB,使用Multipart Upload...
Multipart Upload创建成功,Upload ID:
ZjU2YzkyMDMtN2VjOS00MDM4LTlkY2MtNzRhYTM3ZjA1MTlkLjgxNjEzZTk2LTc3MTUtNDc4MS04NWFjLWY0
ZWU5NjZhMTE4NngxNzUzODkyODQ4NjM1NTA0NTI1
从文件读取到内存: 32768 字节 (总计: 32768/20184976)
...........

从文件读取到内存: 32768 字节 (总计: 5242880/20184976)
从内存上传分块 1 到MinIO,大小: 5242880 字节
分块 1 上传成功,ETag: d871d94bf0052b021048d9bf49d09ce9
从文件读取到内存: 32768 字节 (总计: 5275648/20184976)
从文件读取到内存: 32768 字节 (总计: 5308416/20184976)
...........
从文
从文件读取到内存: 32768 字节 (总计: 10485760/20184976)
从内存上传分块 2 到MinIO,大小: 5242880 字节
分块 2 上传成功,ETag: f53d0a4fa53433a602045abafdd78fd3
从文件读取到内存: 32768 字节 (总计: 10518528/20184976)
从文件读取到内存: 32768 字节 (总计: 10551296/20184976)
...........
从文件读取到内存: 32768 字节 (总计: 15695872/20184976)
从文件读取到内存: 32768 字节 (总计: 15728640/20184976)
从内存上传分块 3 到MinIO,大小: 5242880 字节
分块 3 上传成功,ETag: bb624d69050b1e1eec98897d64aa6e5c
从文件读取到内存: 32768 字节 (总计: 15761408/20184976)
从文件读取到内存: 32768 字节 (总计: 15794176/20184976)
...........
从文件读取到内存: 32768 字节 (总计: 20119552/20184976)
从文件读取到内存: 32768 字节 (总计: 20152320/20184976)
从文件读取到内存: 32656 字节 (总计: 20184976/20184976)
从内存上传分块 4 到MinIO,大小: 4456336 字节

分块 4 上传成功,ETag: 0ee96f2a4d95d43db356889f57f50cbe

完成Multipart Upload...

=== 大文件上传完成 ===
文件上传成功!
总分块数: 4
最终ETag:
文件位置:

注意:文件已成功上传为完整文件。
这模拟了从文件读取32KB数据到内存,然后从内存上传到MinIO的场景。

=== 程序执行完成 ===

3.4 查看上传的文件

4 范例解析-minio_basic文件上传下载

本文档将详细介绍 minio_basic.cpp 文件中的代码实现,帮助开发者理解如何使用 MinIO C++ SDK 进行对象存储的基本操作,包括文件上传和下载。

4.1 程序流程分析

4.1.1 整体流程图

4.1.2 详细操作流程

4.2 代码详解

4.2.1 连接配置部分

// MinIO服务器连接配置
std::string minioEndpoint = "localhost:9000"; // 服务器地址
std::string accessKey = "minioadmin"; // 访问密钥
std::string secretKey = "minioadmin"; // 秘密密钥
bool useSSL = false; // 是否使用SSL

配置说明:

  • minioEndpoint : MinIO服务器的地址和端口
  • accessKey/secretKey : 用于身份验证的密钥对
  • useSSL : 控制是否使用HTTPS连接

4.2.2 客户端初始化

// MinIO服务器地址和端口
// 本地部署:localhost:9000
// 远程服务器:your-server-ip:9000
// 使用HTTPS:your-server-ip:9000
std::string minioEndpoint = "localhost:9000";

// 访问密钥ID (Access Key ID)
// 在MinIO控制台 -> Identity -> Users 中创建用户获取
// 默认管理员账号的Access Key是:minioadmin
std::string accessKey = "minioadmin";

// 秘密访问密钥 (Secret Access Key)
// 在MinIO控制台 -> Identity -> Users 中创建用户获取
// 默认管理员账号的Secret Key是:minioadmin
std::string secretKey = "minioadmin";

// 是否使用SSL/TLS加密连接
// true: 使用HTTPS (https://)
// false: 使用HTTP (http://)
bool useSSL = false;

// ==================== 创建MinIO客户端 ====================
// 初始化MinIO客户端对象,建立与服务器的连接
minio::s3::BaseUrl baseUrl(minioEndpoint, useSSL);
minio::creds::StaticProvider provider(accessKey, secretKey);
minio::s3::Client minio(baseUrl, &provider);

组件说明:

  • BaseUrl : 封装服务器地址和协议信息
  • StaticProvider : 提供静态的访问凭证
  • Client : MinIO操作的主要接口

4.2.3 文件上传实现

4.2.3.1 上传流程图

4.2.3.2 核心代码分析

// 1. 打开文件流
std::ifstream fileStream(filePath, std::ios::binary);
if (!fileStream.is_open()) {
     std::cerr << "无法打开文件: " << filePath << std::endl;
     return 1;
}

// 2. 获取文件大小
fileStream.seekg(0, std::ios::end);
long fileSize = fileStream.tellg();
fileStream.seekg(0, std::ios::beg);

// 3. 创建上传参数
minio::s3::PutObjectArgs args(fileStream, fileSize, 0);
args.bucket = bucketName;
args.object = objectName;

// 4. 执行上传
minio::s3::PutObjectResponse resp = minio.PutObject(args);

参数说明:

  • fileStream : 文件输入流,以二进制模式打开
  • fileSize : 文件大小,用于告知服务器预期数据量
  • args.bucket : 目标存储桶名称
  • args.object : 对象在存储桶中的名称

4.2.4 响应处理

if (!resp) {
    std::cerr << "上传失败: " << resp.Error().String() << std::endl;
    return 1;
}

// 获取响应信息
std::string etag = resp.headers.GetFront("etag");
std::cout << "状态码: " << resp.status_code << std::endl;
std::cout << "ETag: " << resp.etag << std::endl;

响应字段说明:

  • status_code : HTTP状态码
  • etag : 对象的唯一标识符
  • version_id : 对象版本ID(如果启用版本控制)
  • headers : 完整的HTTP响应头

4.2.5 文件下载实现

4.2.5.1 下载流程图

4.2.5.2 回调函数机制

// 设置数据回调函数
args.datafunc = [&outFile](minio::http::DataFunctionArgs dataArgs) -> bool {
      outFile.write(dataArgs.datachunk.c_str(), dataArgs.datachunk.length());
      return true;
};

回调函数说明:

  • 采用Lambda表达式实现
  • dataArgs.datachunk : 接收到的数据块
  • 返回 true 表示继续接收,返回 false 会中断下载

未完

#c++##项目##秋招被确诊为……##牛客创作赏金赛##26届的你,投了哪些公司?#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务