Minio SDK

地址: https://github.com/minio/minio-go

单文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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 的方法,分片上传也在这里提供。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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 信息,并与其分片序号一起保存下来,后面合并代码时会需要

}

中止分片上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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("终止分片上传成功")
}

合并文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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)
}

前端直连下载

预签名下载链接,丢给前端直接下载即可。同理还有单文件上传也可以预签名丢给前端。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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{})
}