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届的你,投了哪些公司?#