You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将本地多个文件合并为单个文件上传至S3(s3fs/boto3实现)

本地多分片文件合并为单个S3对象实现方案

核心依托S3原生的Multipart Upload机制实现,全程不需要在本地提前把数百个分片拼成完整大文件,不会占用额外本地磁盘空间,以下是你需要的s3fs、boto3实现方式,附带一个更轻量的CLI方案。

方案1:boto3实现(可控性最高,推荐生产环境使用)

boto3是AWS官方SDK,直接对接S3分片上传接口,稳定性和性能最好,实现步骤如下:

  • 提前安装依赖:pip install boto3,通过~/.aws/credentials文件、环境变量或者实例角色配置好AK/SK权限,不需要硬编码在代码里
  • 初始化分片上传任务,拿到全局唯一的UploadId
  • 严格按照文件拼接顺序,逐个上传本地分片,每个分片分配从1开始递增的PartNumber,记录每个分片上传后返回的ETag值
  • 所有分片上传完成后,调用完成接口,S3会在服务端自动把所有分片拼接成单个完整对象
    可直接参考的代码片段:
import os
import boto3

# 配置项
TARGET_BUCKET = "你的S3桶名"
TARGET_S3_KEY = "目标文件在S3中的路径,例:data/merged_archive.tar"
LOCAL_PART_DIR = "./local_split_files"  # 本地分片存放的目录

s3_client = boto3.client("s3")
# 初始化分片上传
mpu_task = s3_client.create_multipart_upload(Bucket=TARGET_BUCKET, Key=TARGET_S3_KEY)
upload_id = mpu_task["UploadId"]
uploaded_parts = []

try:
    # 重点:必须严格按照分片的正确拼接顺序排序,建议分片命名时用补零序号比如part001、part002,避免排序错误
    part_list = sorted(os.listdir(LOCAL_PART_DIR))
    for part_idx, part_filename in enumerate(part_list, start=1):
        part_path = os.path.join(LOCAL_PART_DIR, part_filename)
        if not os.path.isfile(part_path):
            continue
        with open(part_path, "rb") as f:
            resp = s3_client.upload_part(
                Bucket=TARGET_BUCKET,
                Key=TARGET_S3_KEY,
                PartNumber=part_idx,
                UploadId=upload_id,
                Body=f
            )
        uploaded_parts.append({
            "PartNumber": part_idx,
            "ETag": resp["ETag"]
        })
    # 所有分片上传完成,触发服务端合并
    s3_client.complete_multipart_upload(
        Bucket=TARGET_BUCKET,
        Key=TARGET_S3_KEY,
        UploadId=upload_id,
        MultipartUpload={"Parts": uploaded_parts}
    )
    print("上传合并完成")
except Exception as e:
    # 上传失败时终止分片任务,避免残留分片产生存储费用
    s3_client.abort_multipart_upload(Bucket=TARGET_BUCKET, Key=TARGET_S3_KEY, UploadId=upload_id)
    raise e

注意:S3要求除了最后一个分片外,其余单个分片大小不能小于5MB,如果你的本地单个分片小于5MB,可以在读取时把多个小分片合并为一个字节流凑够5MB再作为单个Part上传,否则接口会报错。

方案2:s3fs实现(代码量最少,适合测试/非生产场景)

s3fs是把S3桶挂载为本地文件系统的工具,不需要写业务代码,直接用Linux原生命令就能完成拼接:

  • 先安装s3fs,配置好密钥文件权限,把目标桶挂载到本地目录:
    s3fs 你的桶名 /mnt/s3_mount -o passwd_file=~/.s3fs_passwd -o allow_other
  • 确保本地分片按顺序命名(补零序号格式),直接用cat命令按顺序拼接写入挂载目录的目标文件即可:
    cat /local_part_dir/part* > /mnt/s3_mount/merged_target_file
  • 等待命令执行完成,校验文件大小和哈希值和预期一致即可,s3fs会自动在底层处理上传逻辑。

注意:s3fs因为是文件系统封装,大文件上传性能比原生boto3低30%左右,不适合TB级大文件场景。

额外轻量方案:AWS CLI流上传

如果不想写代码也不想挂载文件系统,可以直接用AWS CLI通过管道流上传,全程不生成本地临时文件,命令如下:
cat /local_part_dir/part* | aws s3 cp - s3://你的桶名/merged_target_file
CLI会自动启用分片上传,自动处理分片切分和重试,操作成本最低,只要提前装好AWS CLI并配置好权限就能用。

通用注意事项

  • 所有方案的核心前提是严格保证分片拼接顺序和原文件拆分顺序完全一致,顺序错乱会直接导致最终文件损坏无法使用
  • 所有方案都不需要在本地生成完整的合并后临时文件,不会占用额外本地存储空间
  • 分片上传完成后建议校验最终S3文件的大小、MD5/CRC校验值,确认和源文件一致。

内容的提问来源于stack exchange,提问作者Hasham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:09:20