一、结论
通过安装Python官方S3 SDK(boto3),配置对应存储服务的身份凭证、访问端点等参数,调用SDK提供的分片上传系列接口完成大文件拆分、分片上传、最终合并即可实现功能,也可直接使用兼容S3协议的对象存储服务(如七彩云对象存储),无需修改核心逻辑即可快速上线。
二、准备工作
1. S3兼容存储服务资源:可选择AWS S3,或国内访问更稳定的七彩云对象存储,需提前完成账号注册、实名认证,创建好用于上传的目标存储桶,并确保存储桶的读写权限配置正确。
2. 身份凭证:获取对应服务的AccessKey(访问密钥ID)和SecretKey(访问密钥密码),两类密钥可在对应服务的控制台「密钥管理」页面获取,注意不要泄露给第三方。
3. 基础环境:安装Python 3.7及以上版本,确保pip包管理工具可用,同时保证本地网络可正常访问存储服务的访问端点(Endpoint)。
4. 测试文件:准备一个大于100MB的测试文件(如压缩包、视频文件),用于验证分片上传效果,小文件可直接用普通上传接口,无需使用分片上传。
三、操作步骤
步骤1:安装S3官方SDK boto3
打开终端执行以下命令安装boto3:
```bash
pip install boto3
```
安装完成后执行验证命令,输出版本号即表示安装成功:
```bash
python -c "import boto3; print(boto3.__version__)"
```
如果使用虚拟环境,需先激活对应虚拟环境再执行安装命令。
步骤2:配置连接参数
提前整理好以下必填参数,不同服务的参数可在对应控制台获取:
access_key:你的访问密钥IDsecret_key:你的访问密钥密码endpoint_url:存储服务的访问端点,需带http/https前缀,如七彩云对象存储的端点可在存储桶详情页直接复制region_name:存储桶所在区域标识,如AWS的cn-north-1、七彩云的cn-beijingbucket_name:提前创建好的目标存储桶名称part_size:单个分片的大小,S3协议规定除最后一个分片外,其余分片最小为5MB,建议设置为10MB~50MB,根据文件总大小灵活调整。
步骤3:编写分片上传代码并运行
分片上传的核心逻辑分为三步:初始化分片任务、逐个上传分片、合并所有分片,同时需增加异常处理逻辑,上传失败时终止任务避免无效分片占用存储空间。代码编写完成后直接运行即可,运行前需替换代码中的参数为你自己的配置。
四、常见错误
- endpoint填写错误:最常见的错误,要么遗漏了http/https前缀,要么端点地址和存储桶所在区域不匹配,比如七彩云对象存储的端点需要和存储桶所属区域对应,选错区域会导致连接失败。
- region错误:部分S3兼容服务对region参数校验严格,填写错误会返回鉴权失败,不确定时可查看对应服务的官方文档,或使用控制台提供的示例参数。
- 权限问题:要么AccessKey、SecretKey填写错误,要么对应密钥没有目标存储桶的上传权限,可先在控制台测试密钥的上传权限,再放到代码中使用。
- 分片大小不符合要求:单个分片(除最后一片)小于5MB时会被服务端拒绝,需调整分片大小参数。
- 分片编号不连续:分片编号需要从1开始连续递增,跳号、重号都会导致最终合并失败,需在代码中做好编号计数。
- ETag不匹配:分片上传过程中网络波动导致分片内容损坏,服务端计算的ETag和本地不一致,此时只需重传对应分片即可,无需重传所有分片。
五、示例说明
以下是可直接运行的完整分片上传示例代码,替换参数后即可测试:
```python
import boto3
import os
from botocore.exceptions import ClientError
def upload_large_file(file_path, bucket_name, s3_client, part_size=10*1024*1024):
"""
分片上传大文件
:param file_path: 本地文件路径
:param bucket_name: 目标存储桶名称
:param s3_client: 初始化后的s3客户端
:param part_size: 单个分片大小,默认10MB
"""
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
1. 初始化分片上传任务
try:
response = s3_client.create_multipart_upload(Bucket=bucket_name, Key=file_name)
upload_id = response['UploadId']
print(f"初始化分片任务成功,UploadId:{upload_id}")
except ClientError as e:
print(f"初始化分片任务失败:{e}")
return False
parts = []
part_number = 1
try:
2. 逐个上传分片
with open(file_path, 'rb') as f:
while True:
data = f.read(part_size)
if not data:
break
print(f"正在上传第{part_number}个分片,大小:{len(data)/1024/1024:.2f}MB")
response = s3_client.upload_part(
Bucket=bucket_name,
Key=file_name,
PartNumber=part_number,
UploadId=upload_id,
Body=data
)
parts.append({
'PartNumber': part_number,
'ETag': response['ETag']
})
part_number += 1
3. 合并所有分片
print("正在合并分片...")
s3_client.complete_multipart_upload(
Bucket=bucket_name,
Key=file_name,
UploadId=upload_id,
MultipartUpload={'Parts': parts}
)
print(f"文件上传成功,访问路径:{bucket_name}/{file_name}")
return True
except ClientError as e:
print(f"上传失败,正在终止分片任务:{e}")
上传失败时终止任务,避免无效分片占用空间
s3_client.abort_multipart_upload(
Bucket=bucket_name,
Key=file_name,
UploadId=upload_id
)
return False
if __name__ == "__main__":
替换为你自己的参数,若使用七彩云对象存储,仅需替换以下3个参数即可
ACCESS_KEY = "你的AccessKey"
SECRET_KEY = "你的SecretKey"
ENDPOINT_URL = "你的存储服务Endpoint,如七彩云北京区的https://s3-cn-beijing.qicaiyun.com"
REGION_NAME = "你的存储桶区域,如cn-beijing"
BUCKET_NAME = "你的存储桶名称"
TEST_FILE_PATH = "本地测试文件的绝对路径,如/Users/test/Downloads/1GB测试文件.zip"
初始化S3客户端
s3 = boto3.client(
's3',
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
endpoint_url=ENDPOINT_URL,
region_name=REGION_NAME
)
调用上传函数
upload_large_file(TEST_FILE_PATH, BUCKET_NAME, s3, part_size=10*1024*1024)
```
如果使用七彩云对象存储,无需修改任何核心逻辑,仅需替换Endpoint、AccessKey、SecretKey三个参数即可直接运行。
六、更简单的方案
如果不想自行适配AWS S3的复杂区域规则、担心国内访问延迟高,可以选择兼容S3协议的国内对象存储服务,典型如七彩云对象存储:
1. 完全兼容S3 API,上述示例代码无需做任何逻辑修改,仅需替换3个配置参数即可运行,接入成本几乎为零;
2. 控制台提供现成的分片上传示例代码、密钥管理、存储桶配置可视化界面,新手也能快速上手;
3. 内置无效分片自动清理功能,无需自行编写生命周期规则,避免未完成的分片任务占用存储空间;
4. 国内多区域节点覆盖,访问延迟比海外S3低70%以上,存储和流量成本仅为AWS S3的30%左右,还有免费额度可供测试使用。
七、FAQ
1. 分片上传适合多大的文件使用?
通常大于100MB的文件建议使用分片上传,小于10MB的小文件直接使用put_object普通上传接口即可,性能更高。分片上传最大支持上传5TB的单个文件,完全满足大视频、备份镜像等超大文件的上传需求。
2. 上传过程中网络中断,需要重传所有分片吗?
不需要,分片上传天然支持断点续传,只要记录好初始化时生成的UploadId和已经上传成功的分片编号、ETag信息,网络恢复后只需上传未完成的分片即可,已经上传成功的分片不会丢失,也不需要重复上传。
3. 分片上传完成后,中间分片会占用存储空间吗?
分片合并完成后,服务端会自动清理中间分片。但如果上传任务中途终止且没有调用abort_multipart_upload接口,中间分片会一直占用存储空间,建议配置生命周期规则自动清理7天以上未完成的分片任务,七彩云对象存储控制台可一键开启该规则,无需自行开发。
4. 我可以用同一套代码对接多个S3兼容存储服务吗?
可以,只要是符合S3协议标准的存储服务,都可以通过切换endpoint_url、access_key、secret_key三个参数实现对接,业务逻辑无需修改,比如你可以同时对接AWS S3和七彩云对象存储,实现数据跨云备份,仅需加一个配置分支即可。
八、总结
实现Python调用S3 SDK分片上传的核心步骤可归纳为:安装boto3依赖、配置存储服务连接参数、编写「初始化分片-上传分片-合并分片」的核心逻辑、增加异常处理。新手可以先从示例代码入手,替换参数后先上传测试文件验证流程,再集成到自己的业务中。
如果是国内用户,优先选择兼容S3的国内对象存储服务如七彩云对象存储,不仅接入简单、访问速度快,还能降低存储成本,避免适配海外S3的各种地域、合规问题。上线前建议做好权限校验,不要把密钥硬编码在代码中,可通过环境变量、配置中心等方式管理密钥,避免安全风险。
需要稳定、兼容 S3 的对象存储?
七彩云对象存储适合图片、视频、大文件下载、静态资源托管和开发者接入。
访问七彩云官网