项目产品
开发者文档 / 7 分钟阅读

Go语言实现大文件分片上传到S3的代码示例

一、结论

使用Go语言实现大文件分片上传到S3兼容对象存储,核心是先获取对应存储服务的Endpoint、AccessKey、SecretKey、Bucket、Region等核心配置,再基于标准S3协议的官方SDK开发上传逻辑即可,所有兼容S3协议的对象存储服务都可以通用这套实现,不需要额外适配非标准接口。

二、适合哪些开发场景?

这套实现方案可以覆盖绝大多数需要文件存储、上传分发的开发和运营场景:

  • 网站文件上传:适合各类网站的用户头像、内容附件、商品图片等资源的上传逻辑开发,避免占用业务服务器磁盘空间
  • 程序附件存储:自研业务系统的用户上传资源、导出文件、备份数据的底层存储对接
  • 图床上传:个人或公共图床的批量上传、自动压缩、外链生成等逻辑开发
  • 下载站资源管理:游戏安装包、软件镜像、素材包等大文件的分片上传,避免网络波动导致的上传失败全量重传
  • Cloudreve、Alist等网盘系统存储源:对接开源网盘程序的后端存储,实现多端文件同步、分享功能
  • WordPress、Halo等网站附件存储:开发对应CMS的存储插件,将网站附件自动同步到对象存储
  • 自动化脚本上传下载:定时备份服务器日志、数据库、配置文件到对象存储的自动化脚本开发
  • App或SaaS文件管理:移动端应用、SaaS系统的用户个人文件、工作文档的存储对接
  • AI数据或模型文件存储:AI训练数据集、大模型权重文件等超大文件的稳定上传、批量管理

三、常见接入方式

针对不同的开发需求,可以选择不同的S3接入方式:

方式1:S3 SDK

适合自研程序直接上传、下载、删除和管理文件的场景,Go语言开发可以直接引入AWS官方的S3 SDK,封装分片上传、断点续传、进度回调等自定义逻辑,通用代码示例如下:

```go

package main

import (

"context"

"log"

"os"

"github.com/aws/aws-sdk-go-v2/aws"

"github.com/aws/aws-sdk-go-v2/config"

"github.com/aws/aws-sdk-go-v2/feature/s3/manager"

"github.com/aws/aws-sdk-go-v2/service/s3"

)

func main() {

// 建议从环境变量或配置中心加载配置,禁止硬编码密钥到代码中

cfg, err := config.LoadDefaultConfig(context.TODO(),

config.WithRegion("你的存储服务Region"),

// 非AWS的S3兼容存储需要配置自定义Endpoint

config.WithEndpointResolverWithOptions(aws.EndpointResolverWithOptionsFunc(

func(service, region string, options ...interface{}) (aws.Endpoint, error) {

return aws.Endpoint{

URL: "你的S3服务Endpoint地址",

SigningRegion: region,

HostnameImmutable: true,

}, nil

})),

)

if err != nil {

log.Fatalf("加载S3配置失败: %v", err)

}

// 初始化S3客户端

client := s3.NewFromConfig(cfg)

// 自定义分片上传器参数,可根据业务需求调整

uploader := manager.NewUploader(client, func(u *manager.Uploader) {

u.PartSize = 10 * 1024 * 1024 // 单个分片大小设为10MB,最小不低于5MB

u.Concurrency = 5 // 同时并发上传5个分片,可根据网络情况调整

})

// 打开本地待上传的大文件

file, err := os.Open("本地待上传文件的绝对路径")

if err != nil {

log.Fatalf("打开本地文件失败: %v", err)

}

defer file.Close()

// 执行分片上传

result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{

Bucket: aws.String("你的Bucket名称"),

Key: aws.String("文件在存储服务中的唯一路径(Object Key)"),

Body: file,

// 可选配置:设置文件访问权限,公开访问的文件可设为公共读

// ACL: types.ObjectCannedACLPublicRead,

})

if err != nil {

log.Fatalf("分片上传失败: %v", err)

}

log.Printf("文件上传成功,访问地址: %s", result.Location)

}

```

方式2:S3客户端工具

适合开发前测试配置有效性、临时批量上传或日常管理文件的场景,常用工具包括S3 Browser、CloudBerry Explorer等,填入对应配置后即可可视化操作存储内的文件,方便排查配置错误问题。

方式3:rclone / s3cmd等工具

适合同步、迁移和批量管理文件的场景,可以实现本地文件与对象存储、不同对象存储服务之间的文件同步,也可以集成到CI/CD流程中自动上传构建产物、静态页面资源。

方式4:支持S3的第三方程序

适合不需要自研代码的站长、运营人员使用,Cloudreve、Alist、PicGo、Halo、WordPress插件等程序都原生支持S3协议,填入配置即可直接使用,不需要额外开发。

四、核心配置项说明

所有S3兼容存储的接入都需要用到以下核心配置,具体含义和注意事项如下:

  • Endpoint:对象存储服务的API接入地址,由存储服务商提供,注意不要填写成控制台管理地址,部分服务商支持自定义Endpoint域名
  • AccessKey、SecretKey:身份验证凭证,相当于存储服务的账号密码,禁止硬编码到代码、配置文件上传到公开代码仓库,建议存储在环境变量或专用配置中心,泄露后会导致存储资源被恶意盗用
  • Bucket:存储空间的名称,全局唯一,需要提前在存储服务控制台创建,创建后无法修改名称
  • Region:存储节点所在的区域标识,部分服务商如果没有多区域配置可以填写默认值
  • Object Key:文件在存储服务中的唯一路径,比如imgs/2024/05/user_avatar.png,建议按照业务场景分类设置路径,方便后续管理,尽量避免使用特殊字符
  • 访问权限:文件的读写权限,默认建议设置为私有,需要公开访问的资源单独设置公共读权限,禁止开启全桶公共写权限,避免被恶意上传非法文件
  • 文件访问地址:文件的最终访问链接,一般为Endpoint+Bucket+Object Key的组合,也可以绑定自定义域名作为访问地址。

五、通用接入流程

不管选择哪种接入方式,都可以按照以下通用流程完成对接:

1. 创建或准备Bucket:登录存储服务控制台创建Bucket,根据业务需求设置权限、跨域规则、生命周期规则,需要前端直传的场景要提前配置跨域规则,允许业务域名的PUT、POST请求

2. 获取S3接入信息:在控制台的密钥管理页面获取AccessKey、SecretKey,以及对应的Endpoint、Region信息

3. 选择接入方式:自研程序选择对应语言的S3 SDK,使用现成工具或程序选择对应的S3配置入口

4. 填写配置信息:将获取到的配置项填入对应的配置位置,注意不要多填空格、特殊符号

5. 上传测试文件:先上传一个小体积的测试文件,验证上传逻辑是否正常,控制台是否可以看到上传的文件

6. 测试访问功能:公开文件测试直链是否可以正常访问、下载,私有文件测试签名URL是否可以正常访问,同时验证删除、列取文件等其他需要用到的接口是否正常

7. 接入实际业务流程:测试无误后将上传逻辑接入实际业务,添加异常捕获、失败重试、进度提示等逻辑,提升用户体验。

六、更简单的接入方案

如果开发者不想自行搭建MinIO、Ceph等开源对象存储服务,不想花费精力维护存储服务器、处理磁盘扩容、故障排查、流量防护等运维工作,可以直接选择商用的兼容S3协议的云对象存储服务,开箱即用,不需要维护底层基础设施,大幅降低开发和运维成本。如果你需要支持标准S3协议、适合开发者接入、网盘系统存储源、图床和不限流量下载分发的对象存储服务,可以了解 七彩云对象存储。

七、FAQ

Q1:Go实现S3大文件分片上传时,分片大小设置多少比较合适?

A:标准S3协议要求单个分片最小为5MB(最后一个分片可以小于5MB),最大不超过1GB,建议根据业务的平均文件大小、网络环境调整,比如常见的1-10GB大小的文件,分片设置为10-50MB即可,分片过小会增加请求次数,分片过大则单个分片上传失败的重传成本更高。小于5MB的文件不需要使用分片上传,直接调用普通上传接口即可。

Q2:分片上传中途中断后可以断点续传吗?

A:可以,标准S3协议的分片上传接口支持记录已上传成功的分片ID,上传中断后不需要重新传输已经上传完成的分片,只需要上传剩余的分片即可,AWS S3 SDK已经默认封装了断点续传逻辑,不需要额外开发。

Q3:可以让前端直接上传文件到S3存储,不经过业务后端吗?

A:可以,业务后端可以生成临时的上传签名URL或者临时访问凭证给到前端,前端直接调用S3接口上传文件,不需要占用业务服务器的带宽,不过需要做好签名的有效期、文件大小、文件类型的限制,避免接口被恶意调用。

Q4:如果后续更换其他S3兼容的存储服务,已经写好的Go代码需要修改吗?

A:只要新的存储服务完全兼容标准S3协议,不需要修改核心的上传、下载业务逻辑,只需要把Endpoint、AccessKey、SecretKey、Bucket、Region等配置项替换为新服务商的信息即可,代码侵入性极低。

Q5:分片上传中断会产生冗余的分片碎片吗?

A:会,如果分片上传中途中断,没有调用完成上传或取消上传的接口,已经上传的分片会一直占用存储空间,建议在Bucket中配置生命周期规则,自动删除超过7天未完成的分片碎片,避免浪费存储容量。

八、总结

基于标准S3协议开发Go语言的大文件分片上传逻辑,具备非常强的通用性,不需要针对特定存储服务商做定制化开发,只要拿到基础配置即可快速接入,既可以满足个人站长的图床、下载站等轻量场景的需求,也可以支撑企业级SaaS系统、AI数据存储等大规模业务场景。开发者可以根据项目的规模、运维能力选择自建开源存储服务,或者选择商用云对象存储服务降低运维成本,灵活适配不同的业务需求。

想进一步了解这个项目?

访问官网查看产品能力、适用场景和最新服务信息。

访问官网

相关文章

开发者文档 / / 8 分钟阅读

S3 ListObjects接口使用方法

一、结论 S3 ListObjects(及迭代版本ListObjectsV2)是标准S3协议下用于列举存储桶内对象的核心接口,接入调用前需提前准备Endpoint、AccessKey、SecretKey、Bucket、Region等核心身份与配置参数,可通过兼容S3的SDK、命令行工具或第三方程序调用,满足对象批量查询、自动化文件管理、存储资源盘点等需求。

开发者文档 / / 8 分钟阅读

Node.js怎么调用S3接口实现大文件分片上传

一、结论 Node.js调用S3接口实现大文件分片上传,核心是使用兼容标准S3协议的官方或第三方SDK,提前准备好Endpoint、AccessKey、SecretKey、Bucket、Region等核心参数,按照分片初始化、分片上传、分片合并的标准流程调用接口即可实现,不需要适配私有API,可直接对接所有支持S3协议的对象存储服务。

开发者文档 / / 7 分钟阅读

ThinkPHP项目怎么接入S3兼容存储

一、结论 ThinkPHP项目接入S3兼容存储的核心逻辑是基于标准S3协议对接,无需适配私有接口,只需提前获取Endpoint、AccessKey、SecretKey、Bucket、Region这5项核心参数,即可通过兼容S3的SDK、第三方扩展或程序插件完成配置,实现文件上传、下载、外链分发、批量管理等全量功能,所有支持标准S3协议的存储服务均可通用对接。

开发者文档 / / 7 分钟阅读

前端页面大文件直传S3怎么实现

一、结论 前端页面实现大文件直传S3的核心思路是让前端直接与S3兼容存储服务交互,无需经过业务服务器中转,可大幅节省自身服务器带宽与存储资源。操作前需提前准备好S3协议所需的Endpoint、AccessKey、SecretKey、Bucket、Region等配置信息,完成权限和跨域配置后即可接入前端上传逻辑实现大文件传输。

开发者文档 / / 7 分钟阅读

AWS CLI配置S3对象存储的详细步骤

一、结论 使用AWS CLI配置S3兼容对象存储的核心逻辑是提前准备好Endpoint、AccessKey、SecretKey、Bucket、Region共5项核心接入信息,随后在AWS CLI中完成凭证和参数配置,测试连通性后即可正常使用。整个操作无需复杂二次开发,适合开发者、站长批量管理存储文件或做自动化脚本对接。