minio客户端必须使用minioclient而非awssdk,因其内置适配签名逻辑和endpoint行为;分片上传须遵循标准s3流程,partnumber从1起递增,分片大小最小5mb,推荐5mb以兼容所有版本。

MinIO 客户端初始化必须用 MinioClient,别用 AwsSdk
MinIO 虽兼容 S3 协议,但 C# 里直接上 AwsSdk(AmazonS3Client)容易掉坑:签名版本不一致、预签名 URL 失效、分片上传 CreateMultipartUpload 返回 403。官方 MinioClient 内置适配 MinIO 的签名逻辑和 endpoint 行为,省去手动调 ForcePathStyle 或改 ServiceURL 的麻烦。
实操建议:
- 用 NuGet 安装
Minio包(不是AwsSdk),当前稳定版是4.0.0+ - 初始化时显式关掉 SSL 验证(开发环境):
new MinioClient("https://minio.local:9000", "user", "pass").WithSSLValidation(false) - 生产环境必须开 HTTPS + 合法证书,否则
MinioClient会拒绝连接
PutObjectAsync 不适合大文件,分片得走 ComposeObjectAsync 或原生 multipart
PutObjectAsync 看起来方便,但它把整个文件读进内存再发,100MB 文件就占 200MB+ 内存,还容易触发 OOM 或超时。MinIO 分片上传必须用标准 S3 multipart 流程:先 CreateMultipartUpload → 传多个 UploadPartAsync → 最后 CompleteMultipartUpload。
常见错误现象:
-
UploadPartAsync报错The part number must be an integer between 1 and 10000:说明你传了 0 或负数,partNumber必须从 1 开始递增 - 上传后文件打不开:没调
CompleteMultipartUpload,或Complete时传的Etag列表顺序/数量跟UploadPart不一致 - 并发上传卡死:
UploadPartAsync默认不支持并发,要自己用Task.WhenAll包一层,但注意 MinIO 默认最大并发分片数是 1000,别设太高
分片大小不能乱设:MinIO 要求最小 5MB,最后一片可小于 5MB
这是硬限制。设成 4MB?UploadPartAsync 直接返回 400 错误:EntityTooSmall。设太大(比如 1GB)倒不会报错,但内存压力陡增,失败重传成本高。
参数差异与建议:
- 常规分片大小设
5 * 1024 * 1024(5MB)最稳,兼容所有 MinIO 版本 - 单个文件总分片数不能超 10000,所以最大支持文件 ≈ 50GB(5MB × 10000)
- 最后一片允许
- 别依赖
FileInfo.Length做分片计算,用Stream.Length更准,尤其处理网络流或加密流时
上传进度和断点续传得自己管,MinIO SDK 不提供内置支持
MinioClient 没有 ProgressChanged 事件或回调参数。想显示进度?得在每次 UploadPartAsync 前记下已传字节数;想断点续传?得自己存 uploadId 和每个分片的 Etag 到本地 DB 或文件。
实操要点:
- 进度估算只对已成功上传的分片有效,失败分片要重试后才更新计数
- 断点续传关键字段:上传前保存
bucketName、objectName、uploadId、partNumber → Etag映射 - 恢复上传时,先调
ListPartsAsync拿已传分片列表,再跳过已成功的partNumber - 别把
uploadId存内存 —— 进程重启就丢,MinIO 服务端默认 24 小时自动清理未完成上传
分片上传真正的复杂点不在代码量,而在怎么安全地管理 uploadId 生命周期、怎么应对网络抖动导致的重复上传、以及如何让失败重试不污染已传分片 —— 这些都得靠业务层兜底,SDK 不替你做决定。










