Minio SDK
地址: https://github.com/minio/minio-go
单文件上传
package main
import (
"context"
"log"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
// 创建 minio 客户端对象连接
endpoint := "192.168.0.221:9000"
accessKey := "tvR7984WQeZZig2tWkgE"
secretKey := "Tf0qT98Yh6oGCqqAvHEUVn0liskCe2CHHrhrL1LL"
useSSL := false
minioClient, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
Secure: useSSL,
})
if err != nil {
log.Fatalln("创建客户端失败: " + err.Error())
}
// 上传文件
// 1.创建桶 (bucket)
bucketName := "test-bucket"
location := "company_221_docker"
err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: location})
if err != nil {
// 检查桶是否已经存在
exist, existErr := minioClient.BucketExists(context.Background(), bucketName)
if existErr == nil && exist {
log.Printf("Bucket %s already exists.\n", bucketName)
} else {
log.Fatalln("创建桶失败: " + err.Error())
}
}
log.Printf("Successfully created %s\n", bucketName)
// 2.上传文件对象
filePath := "/Users/yw/Project/go/demo/minio/credentials.json"
uploadFileName := "test-001.json"
contentType := "application/json"
info, err := minioClient.FPutObject(context.Background(), bucketName, uploadFileName, filePath, minio.PutObjectOptions{ContentType: contentType})
if err != nil {
log.Fatalln("上传文件失败" + err.Error())
}
log.Printf("Successfully uploaded %s of size %d\n", uploadFileName, info.Size)
}
分片上传
分片上传使用的 client 对象是 minioCore 对象,该对象提供了更底层的 AWS S3 的方法,分片上传也在这里提供。
package main
import (
"context"
"log"
"net/url"
"time"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
// 创建 minio 客户端对象连接
endpoint := "192.168.0.221:9000"
accessKey := "tvR7984WQeZZig2tWkgE"
secretKey := "Tf0qT98Yh6oGCqqAvHEUVn0liskCe2CHHrhrL1LL"
useSSL := false
minioCore, err := minio.NewCore(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
Secure: useSSL,
})
if err != nil {
log.Fatal("创建客户端失败: " + err.Error())
}
bucketName := "test-bucket"
fileObjName := "测试文件名称.mov"
ctx := context.Background()
uploadID, err := minioCore.NewMultipartUpload(ctx, bucketName, fileObjName, minio.PutObjectOptions{})
if err != nil {
log.Fatal("获取上传 ID 失败: " + err.Error())
}
log.Println("上传 ID: " + uploadID)
// 模拟文件切分后-五个分片
// 貌似 url.Values 可以置空,实际前端请求时 并不需要携带这两个自定义参数
for partNum := 1; partNum <= 5; partNum++ {
// partUploadURL, err := minioCore.Presign(ctx, "POST", bucketName, fileObjName, time.Hour, url.Values{
// "uploadId": []string{uploadID},
// "partNumber": []string{strconv.Itoa(partNum)},
// })
partUploadURL, err := minioCore.Presign(ctx, "POST", bucketName, fileObjName, time.Hour, url.Values{})
if err != nil {
log.Fatal("获取上传地址失败: " + err.Error())
}
log.Println("上传地址: " + partUploadURL.String())
}
// 返回所有的上传分片链接给前端
// 前端使用 post 方法, formData 向改地址提交文件分片数据
// 提交之后获取上传的 Etag 信息,并与其分片序号一起保存下来,后面合并代码时会需要
}
中止分片上传
package main
import (
"context"
"log"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
// 创建 minio 客户端对象连接
endpoint := "192.168.0.221:9000"
accessKey := "tvR7984WQeZZig2tWkgE"
secretKey := "Tf0qT98Yh6oGCqqAvHEUVn0liskCe2CHHrhrL1LL"
useSSL := false
minioCore, err := minio.NewCore(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
Secure: useSSL,
})
if err != nil {
log.Fatal("创建客户端失败: " + err.Error())
}
bucketName := "test-bucket"
fileObjName := "测试文件名称.mov"
// uploadID := "MjM3NmQ2NzMtMTQ5OS00MTkzLWJjMGMtYWRjNjFiNzBiNjJlLjc2OWIwZmU4LTNhMDctNGQyNi04YmQ1LTM0YTA5MzU3MTA0Mg"
uploadID := "MjM3NmQ2NzMtMTQ5OS00MTkzLWJjMGMtYWRjNjFiNzBiNjJlLmQ4Yjk1YzIzLTM2OTItNDFiNi1hOTEzLTgwYjRkYTljNTQ2Mw"
ctx := context.Background()
if err := minioCore.AbortMultipartUpload(ctx, bucketName, fileObjName, uploadID); err != nil {
log.Fatal("终止分片上传失败: " + err.Error())
}
log.Println("终止分片上传成功")
}
合并文件
package main
import (
"context"
"log"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
// 创建 minio 客户端对象连接
endpoint := "192.168.0.221:9000"
accessKey := "tvR7984WQeZZig2tWkgE"
secretKey := "Tf0qT98Yh6oGCqqAvHEUVn0liskCe2CHHrhrL1LL"
useSSL := false
minioCore, err := minio.NewCore(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
Secure: useSSL,
})
if err != nil {
log.Fatal("创建客户端失败: " + err.Error())
}
bucketName := "test-bucket"
fileObjName := "测试文件名称.mov"
uploadID := "MjM3NmQ2NzMtMTQ5OS00MTkzLWJjMGMtYWRjNjFiNzBiNjJlLjc2OWIwZmU4LTNhMDctNGQyNi04YmQ1LTM0YTA5MzU3MTA0Mg"
ctx := context.Background()
// PartNumber 分片的序号
// ETag 分片的ETag 分片校验码,前端上传文件分片之后,返回的校验码
// CompletePart 的顺序必须是 分片序号的 升序排序
info, err := minioCore.CompleteMultipartUpload(ctx, bucketName, fileObjName, uploadID, []minio.CompletePart{
{PartNumber: 1, ETag: "etag1"},
{PartNumber: 2, ETag: "etag2"},
}, minio.PutObjectOptions{})
if err != nil {
log.Fatal("分片上传合并失败: " + err.Error())
}
log.Println("分片上传合并成功: ", info)
}
前端直连下载
预签名下载链接,丢给前端直接下载即可。同理还有单文件上传也可以预签名丢给前端。
package main
import (
"context"
"log"
"net/url"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
// 创建 minio 客户端对象连接
endpoint := "192.168.0.221:9000"
accessKey := "tvR7984WQeZZig2tWkgE"
secretKey := "Tf0qT98Yh6oGCqqAvHEUVn0liskCe2CHHrhrL1LL"
useSSL := false
minioCore, err := minio.NewCore(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
Secure: useSSL,
})
if err != nil {
log.Fatal("创建客户端失败: " + err.Error())
}
bucketName := "test-bucket"
fileObjName := "测试文件名称.mov"
minioCore.PresignedGetObject(context.Background(), bucketName, fileObjName, 60, url.Values{})
}