使用 AWS SDK for C++ TransferManager 实现 Amazon S3 大对象内存流上传下载
【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址: https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples
导读
本文以 transfer-manager 代码示例目录 为核心,深入讲解如何在 AWS SDK for C++ 中利用TransferManager组件,将大文件以**内存流(in-memory stream)**方式上传到 Amazon S3 并下载回内存,全程不落地到本地磁盘。读完本文,你将掌握TransferManager的配置方式、线程池执行器的工作原理、内存流回调解读,以及使用md5sum校验传输完整性的完整实战流程,并了解它与此仓库中S3Client(s3 目录)和S3CrtClient(s3-crt 目录)三条 S3 接入路径的差异与适用场景。
TransferManager 是什么:为什么比裸 S3Client 更适合大对象
官方 README 明确说明:本目录示例采用TransferManager以获得优于S3Client的上传/下载性能。从仓库结构看,AWS SDK for C++ 提供了三条访问 S3 的路径,各有侧重:
- s3 目录:基于
S3Client的标准 API 示例,覆盖CreateBucket、PutObject、GetObject、ListBuckets、对象完整性等大量单动作与场景示例,适合精细控制每一次 API 调用。 - s3-crt 目录:基于
S3CrtClient(AWS Common Runtime 客户端),通过并行请求实现高性能分片上传与 Range GET 下载,并在 s3-crt-demo.cpp 中演示了throughputTargetGbps、partSize等吞吐配置。 - transfer-manager 目录:基于
TransferManager的高级封装,自动将大文件切分为多个分片并发传输,同时允许通过回调把数据流导向自定义目标(如内存缓冲区),本目录唯一示例 transferOnStream.cpp 即展示了这一能力。
简言之,TransferManager隐藏了多线程分片、失败重试、进度追踪等复杂度,让调用方以"文件路径 ↔ S3 对象"或"数据流 ↔ S3 对象"的简洁语义完成传输。
核心示例:transferOnStream.cpp 全流程剖析
本目录唯一的代码示例是 transferOnStream.cpp,它演示"通过内存流使用 TransferManager 上传/下载大对象"。完整流程如下:
- 用本地文件 [LocalFilePath] 上传到 S3 桶 [Bucket] 的对象键 [Key];
- 将该对象从 S3 下载到内存缓冲区(而非本地文件);
- 把内存数据落盘为 [LocalFilePath]_copy,供
md5sum校验两文件内容一致。
命令行参数与用法
程序运行时需传入 3 个位置参数,参数不足时打印如下用法说明并返回 -1:
Usage: <program> [Bucket] [Key] [LocalFilePath]Bucket:目标 S3 桶名称;Key:S3 对象键;LocalFilePath:本地待上传文件路径,下载后校验副本将生成于<LocalFilePath>_copy。
示例:
./run_transferOnStream my-bucket my-large-file /tmp/data.bin # 校验上传文件与内存下载落盘的副本是否一致 md5sum /tmp/data.bin /tmp/data.bin_copy内存流实现:自定义 IOStream
为了把下载数据接进内存,示例自定义了继承Aws::IOStream的流类型(见 transferOnStream.cpp):
class MyUnderlyingStream : public Aws::IOStream { public: using Base = Aws::IOStream; // Provide a customer-controlled streambuf to hold data from the bucket. explicit MyUnderlyingStream(std::streambuf* buf) : Base(buf) {} ~MyUnderlyingStream() override = default; };其核心是注入调用方控制的std::streambuf,从而把 SDK 写出的字节导向由Aws::Utils::Stream::PreallocatedStreamBuf包装的预分配内存缓冲区。
关键缓冲与线程池配置
static const size_t BUFFER_SIZE = 512 * 1024 * 1024; // 512MB BufferBUFFER_SIZE定义接收缓冲区大小为512MB,需保证大于待下载对象大小;PooledThreadExecutor以25 个线程的线程池驱动分片并发传输(见 transferOnStream.cpp),线程数可按机器核数与带宽调整;PreallocatedStreamBuf streamBuffer(...)使用buffer.GetUnderlyingData()与buffer.GetLength()包装预分配内存,源码注释特别强调:该局部变量被 lambda 按引用捕获,必须存活到transfer_manager全部下载任务完成,否则会导致悬垂引用——这是内存流方案最重要的生命周期约束。
客户端、配置与 TransferManager 创建
auto s3_client = Aws::MakeShared<Aws::S3::S3Client>("S3Client"); auto executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 25); Aws::Transfer::TransferManagerConfiguration transfer_config(executor.get()); transfer_config.s3Client = s3_client; ... auto transfer_manager = Aws::Transfer::TransferManager::Create(transfer_config);要点:
TransferManagerConfiguration必须指定执行器(executor)与底层S3Client;s3Client也可传入自定义配置(区域、凭证、Endpoint 等)的S3Client,从而在传输层之上复用既有的客户端级设置;TransferManager::Create返回shared_ptr,内部负责调度上传/下载任务到线程池。
上传:UploadFile 与状态等待
auto uploadHandle = transfer_manager->UploadFile(LOCAL_FILE, BUCKET, KEY, "text/plain", Aws::Map<Aws::String, Aws::String>()); uploadHandle->WaitUntilFinished(); bool success = uploadHandle->GetStatus() == Transfer::TransferStatus::COMPLETED;UploadFile参数依次为:本地文件路径、桶名、对象键、Content-Type(此处为"text/plain")、自定义元数据 Map;WaitUntilFinished()阻塞当前线程直至任务结束(异步场景下可改用回调监听);GetStatus()返回TransferStatus枚举,与TransferStatus::COMPLETED比较判断成败;- 失败时通过
GetLastError()获取AWSError,打印err.GetMessage()定位原因。
下载到内存:lambda 回调流
auto downloadHandle = transfer_manager->DownloadFile(BUCKET, KEY, [&]() { return Aws::New<MyUnderlyingStream>("TestTag", &streamBuffer); }); downloadHandle->WaitUntilFinished();DownloadFile的重载接收一个返回shared_ptr<IOStream>的工厂回调:SDK 每次需要写目标流时都会调用该 lambda,从而把对象内容持续写入streamBuffer对应的内存。注意"TestTag"是 AWS 内存分配的标签名,便于内存跟踪工具归类。
下载完成后,示例执行了两重正确性验证:
assert(downloadHandle->GetBytesTotalSize() == downloadHandle->GetBytesTransferred());- 断言总字节数等于已传输字节数,从 SDK 侧确认下载完整无缺失;
- 随后把
buffer中的内存数据按GetBytesTransferred()实际长度写入[LocalFilePath]_copy,供外部工具比对。
构建与运行:从 CMakeLists 看编译链路
仓库为每个服务子目录提供 CMake 构建文件,本目录的 CMakeLists.txt 关键点如下:
- 最低 CMake 版本
3.13,项目名tm-examples,C++ 标准C++11; set(SERVICE_COMPONENTS transfer)与find_package(AWSSDK REQUIRED COMPONENTS ${SERVICE_COMPONENTS}):必须安装并链接 SDK 的transfer组件(transfer组件依赖s3与core组件);file(GLOB ... "*.cpp")自动收集目录下全部源文件,并为每个源文件生成run_<源文件名>可执行目标,同时以target_link_libraries(... ${AWSSDK_LINK_LIBRARIES})链接 SDK 库;- 默认开启
BUILD_SHARED_LIBS(共享库),Windows/MSVC 下通过AWSSDK_CPY_DYN_LIBS把运行期 DLL 复制到输出目录; - 若存在
tests/test_<名称>.cpp且启用了BUILD_TESTING,会额外生成test_<名称>测试目标并注册到 CTest。
典型的配置与构建命令(需先完成 AWS SDK for C++ 的安装,参见 cpp/README.rst 中的 Prerequisites 部分):
cmake -S cpp/example_code/transfer-manager -B build/transfer-manager \ -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF cmake --build build/transfer-manager --target run_transferOnStream构建产物run_transferOnStream位于 build 目录,按上文命令行参数直接运行即可。仓库根目录的 run_automated_tests.py 也提供了自动化测试入口(如python3 run_automated_tests.py -23 -s s3),并支持通过PARALLEL_BUILD环境变量开启并行编译。
运行前的必要准备与安全提示
原 README 强调,运行示例前必须先完成 AWS SDK for C++ 的安装与设置(即 Getting Started 流程),并参考代码示例的结构说明完成构建。同时注意以下要点(见 transfer-manager/README.md):
- 最小权限原则:仅为代码授予完成该任务所需的最低 IAM 权限(本示例至少需要目标桶的
s3:PutObject与s3:GetObject); - 区域可用性:代码未经所有 AWS 区域测试,部分服务仅在特定区域可用;
- 费用提醒:运行示例(含单元测试)可能产生 AWS 账户费用;
- 凭证配置:示例通过默认凭证链获取 AWS 凭证,运行前需确保本地已配置凭证(如环境变量或
~/.aws/credentials)。
相关资源与延伸阅读
- 本示例源码:transferOnStream.cpp
- 构建配置:CMakeLists.txt
- 面向
S3Client的标准 API 示例:cpp/example_code/s3/README.md - 面向
S3CrtClient的高吞吐分片示例:cpp/example_code/s3-crt/README.md 与 s3-crt-demo.cpp - C++ 示例的整体构建与自动化测试说明:cpp/README.rst
若你追求极致吞吐且希望 SDK 自动完成分片并行传输,可进一步参考 s3-crt 目录中对throughputTargetGbps、partSize的配置方式(见 s3-crt-demo.cpp),在TransferManagerConfiguration之外为 S3 大对象传输提供另一条高性能路径。
【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址: https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考