欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang使用MinIO的方案詳解

 更新時(shí)間:2023年08月19日 09:48:20   作者:HumbleSwage  
這篇文章主要介紹了Golang使用MinIO的過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

最近在使用Golang做了一個(gè)網(wǎng)盤項(xiàng)目(學(xué)習(xí)),文件存儲(chǔ)一直保存在本地(各廠商提供的oss貴),所以就在思考怎么來處理這些文件,類似的方案很對(duì)hdfs、fastdfs,但這其中MinIO是最近幾年比較火熱的一個(gè)項(xiàng)目,所以嘗試使用這個(gè)試一試。

1、MinIO的安裝

MinIO的安裝特別簡(jiǎn)單,大家可以前去官網(wǎng)按照步驟完成,注意以下幾點(diǎn)即可

  • 注意你服務(wù)器是amd還是arm架構(gòu)
  • 注意你自己的網(wǎng)絡(luò)
  • 確保你按照官網(wǎng)的命令開啟了minio服務(wù)
minio server ~/minio --console-address :9090

目前不要隨便亂修改,按照原始的方案

2、創(chuàng)建Golang項(xiàng)目

mkdir minio-api
cd minio-api
go mod init v1

3、Goland打開項(xiàng)目構(gòu)建一個(gè)上傳文件demo

創(chuàng)建一個(gè)main.go,在這個(gè)函數(shù)中我們首先創(chuàng)建一個(gè)用于初始化MinIOClient的函數(shù),該函數(shù)細(xì)節(jié)如下:

func InitMinioClient() *minio.Client {
	// 基本的配置信息
	endpoint := "172.16.59.130:9000"
	accessKeyID := "IdoSKNGz7evlQXVVqGJF"
	secretAccessKey := "s4hnwC9yWOsU8TTmODFcMcw0TdExa4GsTpGzibEc"
	// 初始化一個(gè)minio客戶端對(duì)象
	minioClient, err := minio.New(endpoint, &minio.Options{
		Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
	})
	if err != nil {
		log.Fatalf("初始化MinioClient錯(cuò)誤:%s", err.Error())
	}
	return minioClient
}

有幾點(diǎn)基本的注意事項(xiàng),首先是基本的配置信息你需要更改為你自己的,一般端口都為9000(注意不是9090),針對(duì)這個(gè)地方的accessKeyID和secretAccessKey的創(chuàng)建如下圖:

在這里插入圖片描述

然后我們構(gòu)建一個(gè)main函數(shù),在這個(gè)main函數(shù)中,我們首先調(diào)用初始化客戶端的函數(shù)InitMinioClient,然后我們?cè)趍ain實(shí)現(xiàn)一個(gè)簡(jiǎn)單的上傳文件的demo

func main() {
	// 創(chuàng)建客戶端
	minioClient := InitMinioClient()
	// bucket名稱
	bucketName := "mypic"
	ctx := context.Background()
	// 創(chuàng)建這個(gè)bucket
	err := minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{})
	if err != nil {
		// 檢測(cè)這個(gè)bucket是否已經(jīng)存在
		exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
		if errBucketExists == nil && exists {
			log.Printf("We already own %s\n", bucketName)
		} else {
			log.Fatalln(err)
		}
	} else {
		log.Printf("Successfully created %s\n", bucketName)
	}
	// 需要上傳文件的基本信息
	objectName := "頭像.jpg"
	filePath := "image"
	contentType := "multipart/form-data"
	fPath := filepath.Join(filePath, objectName)
	fileInfo, err := os.Stat(fPath)
	if err == os.ErrNotExist {
		log.Printf("%s目標(biāo)文件不存在", fPath)
	}
	f, err := os.Open(fPath)
	if err != nil {
		return
	}
	uploadInfo, err := minioClient.PutObject(ctx, bucketName, objectName, f, fileInfo.Size(), minio.PutObjectOptions{ContentType: contentType})
	if err != nil {
		log.Fatalln(err)
	}
	log.Printf("Successfully uploaded %s of size %d\n", objectName, uploadInfo.Size)
}

在這里插入圖片描述

上傳文件即成功,然后打開網(wǎng)頁(yè)頁(yè)面刷新,出現(xiàn)下面頁(yè)面即可,同時(shí)你打開你的服務(wù)器可以發(fā)現(xiàn)你上傳的文件。

在這里插入圖片描述

觀察上面的代碼,至少包括三個(gè)API,包括創(chuàng)建Bucket、檢測(cè)Bucket是否存在、上傳文件到指定的Bucket。為了更好的研究這些API,現(xiàn)在我從Bucket開始研究一下常用的API。

4.創(chuàng)建客戶端對(duì)象

API接口

New(endpoint string, opts *Options) (*Client, error)

初步觀察這個(gè)接口,在結(jié)合我們上面的示例,可以發(fā)現(xiàn):

  • endpoint:目前存儲(chǔ)地址(127.0.0.1:9000),當(dāng)然這里需要根據(jù)自身開啟的minio服務(wù)所在的位置和服務(wù)端口。
  • opts:這個(gè)是一個(gè)minio.Options對(duì)象,然后我們來具體了解一哈這個(gè)對(duì)象有哪些常用的屬性(注意這些屬性的類):
    • Creds:存儲(chǔ)的一個(gè)身份信任
    • Secure:API的請(qǐng)求方式(HTTP/HTTPS)
  • 完整的一個(gè)創(chuàng)建Client的代碼(可以根據(jù)自身需要再改造)
func InitMinioClient() *minio.Client {
	// 基本的配置信息
	endpoint := "172.16.59.130:9000"
	accessKeyID := "IdoSKNGz7evlQXVVqGJF"
	secretAccessKey := "s4hnwC9yWOsU8TTmODFcMcw0TdExa4GsTpGzibEc"
	// 初始化一個(gè)minio客戶端對(duì)象
	minioClient, err := minio.New(endpoint, &minio.Options{
		Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
	})
	if err != nil {
		log.Fatalf("初始化MinioClient錯(cuò)誤:%s", err.Error())
	}
	return minioClient
}

你自己可以嘗試:創(chuàng)建一個(gè)bucket01和bucket02

5.Bucket的基本操作

5.1 創(chuàng)建Bucket

MakeBucket(ctx context.Context, bucketName string, opts MakeBucketOptions)

前兩個(gè)參數(shù)不作過多的介紹,非常的清晰(所謂的BuketName,你可以簡(jiǎn)單理解為就是你文件保存的文件夾),在這里我們?cè)敿?xì)得介紹一哈MakeBucketOptions(minio.MakeBucketOptions),其主要是用于指定Bucket的一些選項(xiàng)比如說 Region (這個(gè)地方的Region表示在哪里創(chuàng)建你的Bucket,默認(rèn)為 us-east-1 ,其它的一些選項(xiàng)可以參考官網(wǎng)文檔,在這里需要注意,如果你是自己服務(wù)器搭建,而不是使用他所提供的存儲(chǔ)服務(wù),其實(shí)你是不用指定這個(gè),就默認(rèn)值問題也不大),一個(gè)完整的示例如下(確保你事先已經(jīng)有這樣的 minioClient ):

err = minioClient.MakeBucket(context.Background(),minio.MakeBucketOptions{Region: "us-east-1", ObjectLocking: true})
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println("Successfully created mybucket.")

5.2 展示Bucket

ListBuckets(ctx context.Context) ([]BucketInfo, error)

這個(gè)接口非常明了,返回的是一個(gè)BucketInfo的slice,在這里我們可以遍歷該元素然后獲取到對(duì)應(yīng)的BucketInfo對(duì)象,直接看下面的demo:

func ListBuckets(minioClient *minio.Client) {
	bucketInfos, err := minioClient.ListBuckets(context.Background())
	if err != nil {
		fmt.Println("List Buckets err:", err.Error())
		return
	}
	for index, bucketInfo := range bucketInfos {
		fmt.Printf("List Bucket No {%d}----filename{%s}-----createTime{%s}\n", index+1, bucketInfo.Name, bucketInfo.CreationDate.Format("2006-01-02 15:04:05"))
	}
}

輸出為:

List Bucket No {1}----filename{bucket01}-----createTime{2023-08-18 04:03:18}
List Bucket No {2}----filename{bucket02}-----createTime{2023-08-18 03:54:42}
注意:bucket是不支持修改名稱的,如果你要修改名稱,一般是新建一個(gè)bucket然后講原來需要改名的bucket的內(nèi)容移到新建的一個(gè)bucket。

5.3 檢測(cè)Bucket

BucketExists(ctx context.Context, bucketName string) (found bool, err error)

檢查Bucket是否存在,查看下面demo:

func CheckBuckets(minioClient *minio.Client) {
	bucketName01 := "bucket01"
	bucketName02 := "bucket03"
	isExist, err := minioClient.BucketExists(context.Background(), bucketName01)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName01, err.Error())
		return
	}
	if isExist {
		fmt.Printf("%s exists!\n", bucketName01)
	} else {
		fmt.Printf("%s not exists!\n", bucketName01)
	}
	isExist, err = minioClient.BucketExists(context.Background(), bucketName02)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName02, err.Error())
		return
	}
	if isExist {
		fmt.Printf("%s exists!\n", bucketName02)
	} else {
		fmt.Printf("%s not exists!\n", bucketName02)
	}
}

輸出:

bucket01 exists!

bucket03 not exists!

5.4 刪除Bucket

RemoveBucket(ctx context.Context, bucketName string) error

刪除名稱為bucketName的bucket,刪除之前建議先檢查該bucket是否存在,查看下面的demo:

func RemoveBucket(minioClient *minio.Client) {
	bucketName01 := "bucket01"
	isExist, err := minioClient.BucketExists(context.Background(), bucketName01)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName01, err.Error())
		return
	}
	if isExist {
		fmt.Printf("%s exists! Start delete....\n", bucketName01)
		// 開始刪除邏輯
		err = minioClient.RemoveBucket(context.Background(), bucketName01)
		if err != nil {
			fmt.Printf("Fail to remove %s:%s\n", bucketName01, err.Error())
			return
		}
		fmt.Printf("Success to remove %s\n", bucketName01)
	} else {
		fmt.Printf("%s not exists!\n", bucketName01)
	}
}

輸出為:

bucket01 exists! Start delete…

Success to remove bucket01

5.6 展示對(duì)象Object

ListObjects(ctx context.Context, bucketName string, opts ListObjectsOptions) <-chan ObjectInfo

展示一個(gè)Object中的所有對(duì)象,注意返回的是一個(gè)channel。在查看下面的demo,請(qǐng)參考之前的內(nèi)容先上傳一些對(duì)象:

func ListObjects(minioClient *minio.Client) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	bucketName := "bucket02"
	opts := minio.ListObjectsOptions{
		Prefix:    "頭",
		Recursive: true,
	}
	objectCh := minioClient.ListObjects(ctx, bucketName, opts)
	for obj := range objectCh {
		fmt.Printf("Name:%s\tSize:%d\tMD5:%s\tModifiedTime:%s\n",
			obj.Key, obj.Size, obj.ETag, obj.LastModified.Format("2006-01-02 03:04:05"))
	}
}

輸出為:

Name:頭像.jpg Size:739938 MD5:10bf76e379cd8f381791c6924f33dcd6 ModifiedTime:2023-08-18 05:22:34
注意,在這里Prefix就是所有Object的的前綴。

針對(duì)Bucket的操作就到這里,但是minio還提供其余操作,比喻設(shè)置tag等等,上面所列舉的是常用的一些操作

6. Object操作

6.1 獲取Object

GetObject(ctx context.Context, bucketName, objectName string, opts GetObjectOptions) (*Object, error)

返回一個(gè)數(shù)據(jù)流對(duì)象,注意是一個(gè)數(shù)據(jù)流,所以要寫入到一個(gè)具體的對(duì)象中,詳見下面demo的使用:

func GetObjects(minioClient *minio.Client) {
	bucketName := "bucket02"
	objectName := "頭像.jpg"
	object, err := minioClient.GetObject(context.Background(), bucketName, objectName, minio.GetObjectOptions{})
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func(object *minio.Object) {
		err := object.Close()
		if err != nil {
			fmt.Println(err)
			return
		}
	}(object)
	localFile, err := os.Create("image/local-file.jpg")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func(localFile *os.File) {
		err := localFile.Close()
		if err != nil {
			return
		}
	}(localFile)
	if _, err = io.Copy(localFile, object); err != nil {
		fmt.Println(err)
		return
	}
}

注意這個(gè)地方文件的寫入。

6.2 放入Object

PutObject(ctx context.Context, bucketName, objectName string, reader io.Reader, objectSize int64,opts PutObjectOptions) (info UploadInfo, err error)

將一個(gè)文件放入到bucket中,詳細(xì)見下面的操作,其實(shí)之前我們的demo中已經(jīng)有了這個(gè)操作:

func PutObjects(minioClient *minio.Client) {
	bucketName := "bucket02"
	// 檢查bucket是否存在
	isExist, err := minioClient.BucketExists(context.Background(), bucketName)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName, err.Error())
		return
	}
	if !isExist {
		fmt.Printf("%s not exists!\n", bucketName)
	}
	// 對(duì)象信息
	objectName := "頭像.jpg"
	filePath := "image"
	contentType := "multipart/form-data"
	fPath := filepath.Join(filePath, objectName)
	// 讀取對(duì)象流
	fileInfo, err := os.Stat(fPath)
	if err == os.ErrNotExist {
		log.Printf("%s目標(biāo)文件不存在", fPath)
	}
	f, err := os.Open(fPath)
	if err != nil {
		log.Printf("%s打開目標(biāo)文件", fPath)
		return
	}
	// 上傳文件
	uploadInfo, err := minioClient.PutObject(context.Background(), bucketName,
		objectName, f, fileInfo.Size(),
		minio.PutObjectOptions{ContentType: contentType})
	if err != nil {
		log.Fatalln(err)
		return
	}
	log.Printf("Successfully uploaded %s of size %d\n", objectName, uploadInfo.Size)
}

最后這個(gè)文件會(huì)被放在你minio服務(wù)器上的minio下,你可以去該文件下查看

在這里插入圖片描述

6.3 復(fù)制Objects

CopyObject(ctx context.Context, dst CopyDestOptions, src CopySrcOptions) (UploadInfo, error)

將一個(gè)文件復(fù)制到另一個(gè)bucket中,詳見下面demo:

func CopyObjects(minioClient *minio.Client) {
	// Source object
	srcOpts := minio.CopySrcOptions{
		Bucket: "bucket02",
		Object: "頭像.jpg",
	}
	// Destination object
	dstOpts := minio.CopyDestOptions{
		Bucket: "bucket01",
		Object: "圖片.jpg",
	}
	// copy
	uploadInfo, err := minioClient.CopyObject(context.Background(), dstOpts, srcOpts)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Successfully copied object:", uploadInfo)
}

輸出為:Successfully copied object: {bucket01 圖片.jpg 10bf76e379cd8f381791c6924f33dcd6 0 2023-08-18 08:144.773 +0000 UTC 0001-01-01 00:00:00 +0000 UTC }

6.4 狀態(tài)Objects

StatObject(ctx context.Context, bucketName, objectName string, opts StatObjectOptions) (ObjectInfo, error)

返回一個(gè)object的元數(shù)據(jù),demo如下:

func StateObjects(minioClient *minio.Client) {
	ObjInfo, err := minioClient.StatObject(context.Background(), "bucket02", "頭像.jpg", minio.StatObjectOptions{})
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("LastModified:%s\tETag:%s\tContentType:%s\tSize:%d\n",
		ObjInfo.LastModified.Format("2006-01-02 03:04:05"),
		ObjInfo.ETag, ObjInfo.ContentType, ObjInfo.Size)
}

輸出為:LastModified:2023-08-18 05:22:34 ETag:10bf76e379cd8f381791c6924f33dcd6 ContentType:multipart/form-data Size:739938

6.5 刪除Object

RemoveObject(ctx context.Context, bucketName, objectName string, opts minio.RemoveObjectOptions) error

刪除一個(gè)object,注意下面demo:

func RemoveObject(minioClient *minio.Client) {
	opts := minio.RemoveObjectOptions{}
	err := minioClient.RemoveObject(context.Background(), "bucket01", "圖片.jpg", opts)
	if err != nil {
		fmt.Println(err)
		return
	}
}

6.6 批量刪除Object

RemoveObjects(ctx context.Context, bucketName string, objectsCh <-chan ObjectInfo, opts RemoveObjectsOptions) <-chan RemoveObjectError

批量刪除一個(gè)bucket中的object,關(guān)鍵就是構(gòu)造這里的objectsCh,詳細(xì)見demo:

func RemoveObjects(minioClient *minio.Client) {
	objectsCh := make(chan minio.ObjectInfo)
	// 注意一般不要自己來構(gòu)造,直接選擇從bucket中查詢,查詢到的對(duì)象放入objectsCh
	for object := range minioClient.ListObjects(context.Background(), "bucket02", minio.ListObjectsOptions{}) {
		if object.Key == "頭像.jpg" {
			objectsCh <- object
		}
	}
	defer close(objectsCh)
	// 刪除
	for rErr := range minioClient.RemoveObjects(context.Background(), "bucket02", objectsCh, minio.RemoveObjectsOptions{}) {
		fmt.Println("Delete err:", rErr.Err.Error())
	}
}

6.7 上傳大對(duì)象Object

FPutObject(ctx context.Context, bucketName, objectName, filePath, opts PutObjectOptions) (info UploadInfo, err error)

該demo如下:

func UploadLargeFileObjects(minioClient *minio.Client) {
	uploadInfo, err := minioClient.FPutObject(context.Background(), "bucket02", "test.csv", "data", minio.PutObjectOptions{
		ContentType: "application/csv",
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Successfully uploaded object: ", uploadInfo)
}

在MinIO中,PutObject和FPutObject主要有以下幾點(diǎn)區(qū)別:

  • 操作對(duì)象方式不同:
    • PutObject上傳對(duì)象采用單個(gè)對(duì)象上傳方式,一次請(qǐng)求上傳一個(gè)對(duì)象。
    • FPutObject上傳對(duì)象采用分片上傳方式,可以在多個(gè)請(qǐng)求中上傳同一個(gè)對(duì)象。
  • 適用場(chǎng)景不同:
    • PutObject適用于小對(duì)象的上傳。
    • FPutObject適用于大對(duì)象的上傳,可以支持超過5GB的對(duì)象上傳。
  • 上傳方式不同:
    • PutObject直接上傳對(duì)象。
    • FPutObject需要首先調(diào)用InitiateMultipartUpload初始化分片上傳,然后調(diào)用UploadPart上傳每個(gè)分片,最后調(diào)用CompleteMultipartUpload完成上傳。
  • 錯(cuò)誤處理不同:
    • PutObject上傳錯(cuò)誤需要重新上傳整個(gè)對(duì)象。
    • FPutObject上傳錯(cuò)誤只需要重新上傳出錯(cuò)的分片。
  • 上傳事務(wù)不同:
    • PutObject上傳具有原子性,一個(gè)對(duì)象要么完全上傳,要么失敗。
    • FPutObject上傳可以暫停和恢復(fù),但多個(gè)分片上傳完成后才視為成功。

所以簡(jiǎn)單來說,對(duì)于小對(duì)象可以直接使用PutObject,對(duì)于大對(duì)象建議使用FPutObject分片上傳。

6.8 下載大對(duì)象

FGetObject(ctx context.Context, bucketName, objectName, filePath string, opts GetObjectOptions) error

下載大文件,詳見下面demo:

func DownloadLargeFileObjects(minioClient *minio.Client) {
	err := minioClient.FGetObject(context.Background(), "bucket02", "test.csv", "/tmp/myobject", minio.GetObjectOptions{})
	if err != nil {
		fmt.Println(err)
		return
	}
}

基本上的操作就是這樣,當(dāng)然這里還可以需要設(shè)置一些策略設(shè)置就不在這里詳講了,可以去官網(wǎng)查看.

完整代碼:

package main
import (
	"context"
	"fmt"
	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"io"
	"log"
	"os"
	"path/filepath"
)
func InitMinioClient() *minio.Client {
	// 基本的配置信息
	endpoint := "172.16.59.129:9000"
	accessKeyID := "6b6U1MlseU8h9dDkACNj"
	secretAccessKey := "Hf6NSEHjXwHiApoymYR0yktNUkbZwt3MYYRmXOgT"
	// 初始化一個(gè)minio客戶端對(duì)象
	minioClient, err := minio.New(endpoint, &minio.Options{
		Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
	})
	if err != nil {
		log.Fatalf("初始化MinioClient錯(cuò)誤:%s", err.Error())
	}
	return minioClient
}
func main() {
	// 創(chuàng)建客戶端
	minioClient := InitMinioClient()
	// Make a new bucket called mymusic.
	// bucketName := "mypic"
	//ctx := context.Background()
	//err := minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{})
	//if err != nil {
	//	// Check to see if we already own this bucket (which happens if you run this twice)
	//	exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
	//	if errBucketExists == nil && exists {
	//		log.Printf("We already own %s\n", bucketName)
	//	} else {
	//		log.Fatalln(err)
	//	}
	//} else {
	//	log.Printf("Successfully created %s\n", bucketName)
	//}
	//
	 Upload the zip file
	//objectName := "頭像.jpg"
	//filePath := "image"
	//contentType := "multipart/form-data"
	//fPath := filepath.Join(filePath, objectName)
	//fileInfo, err := os.Stat(fPath)
	//if err == os.ErrNotExist {
	//	log.Printf("%s目標(biāo)文件不存在", fPath)
	//}
	//
	//f, err := os.Open(fPath)
	//if err != nil {
	//	return
	//}
	//
	//uploadInfo, err := minioClient.PutObject(ctx, bucketName, objectName, f, fileInfo.Size(), minio.PutObjectOptions{ContentType: contentType})
	//if err != nil {
	//	log.Fatalln(err)
	//}
	//
	//log.Printf("Successfully uploaded %s of size %d\n", objectName, uploadInfo.Size)
	// ListBuckets(minioClient)
	//CheckBuckets(minioClient)
	//RemoveBucket(minioClient)
	//UploadObjToBucket(minioClient)
	//ListObjects(minioClient)
	//GetObjects(minioClient)
	//CopyObjects(minioClient)
	//StateObjects(minioClient)
	//RemoveObject(minioClient)
	RemoveObjects(minioClient)
}
func ListBuckets(minioClient *minio.Client) {
	bucketInfos, err := minioClient.ListBuckets(context.Background())
	if err != nil {
		fmt.Println("List Buckets err:", err.Error())
		return
	}
	for index, bucketInfo := range bucketInfos {
		fmt.Printf("List Bucket No {%d}----filename{%s}-----createTime{%s}\n", index+1, bucketInfo.Name, bucketInfo.CreationDate.Format("2006-01-02 15:04:05"))
	}
}
func CheckBuckets(minioClient *minio.Client) {
	bucketName01 := "bucket01"
	bucketName02 := "bucket03"
	isExist, err := minioClient.BucketExists(context.Background(), bucketName01)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName01, err.Error())
		return
	}
	if isExist {
		fmt.Printf("%s exists!\n", bucketName01)
	} else {
		fmt.Printf("%s not exists!\n", bucketName01)
	}
	isExist, err = minioClient.BucketExists(context.Background(), bucketName02)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName02, err.Error())
		return
	}
	if isExist {
		fmt.Printf("%s exists!\n", bucketName02)
	} else {
		fmt.Printf("%s not exists!\n", bucketName02)
	}
}
func RemoveBucket(minioClient *minio.Client) {
	bucketName01 := "bucket01"
	isExist, err := minioClient.BucketExists(context.Background(), bucketName01)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName01, err.Error())
		return
	}
	if isExist {
		fmt.Printf("%s exists! Start delete....\n", bucketName01)
		// 開始刪除邏輯
		err = minioClient.RemoveBucket(context.Background(), bucketName01)
		if err != nil {
			fmt.Printf("Fail to remove %s:%s\n", bucketName01, err.Error())
			return
		}
		fmt.Printf("Success to remove %s\n", bucketName01)
	} else {
		fmt.Printf("%s not exists!\n", bucketName01)
	}
}
func ListObjects(minioClient *minio.Client) {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	bucketName := "bucket02"
	opts := minio.ListObjectsOptions{
		Prefix:    "頭",
		Recursive: true,
	}
	objectCh := minioClient.ListObjects(ctx, bucketName, opts)
	for obj := range objectCh {
		fmt.Printf("Name:%s\tSize:%d\tMD5:%s\tModifiedTime:%s\n",
			obj.Key, obj.Size, obj.ETag, obj.LastModified.Format("2006-01-02 03:04:05"))
	}
}
func GetObjects(minioClient *minio.Client) {
	bucketName := "bucket02"
	objectName := "頭像.jpg"
	object, err := minioClient.GetObject(context.Background(), bucketName, objectName, minio.GetObjectOptions{})
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func(object *minio.Object) {
		err := object.Close()
		if err != nil {
			fmt.Println(err)
			return
		}
	}(object)
	localFile, err := os.Create("image/local-file.jpg")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func(localFile *os.File) {
		err := localFile.Close()
		if err != nil {
			return
		}
	}(localFile)
	if _, err = io.Copy(localFile, object); err != nil {
		fmt.Println(err)
		return
	}
}
func PutObjects(minioClient *minio.Client) {
	bucketName := "bucket02"
	// 檢查bucket是否存在
	isExist, err := minioClient.BucketExists(context.Background(), bucketName)
	if err != nil {
		fmt.Printf("Check %s err:%s", bucketName, err.Error())
		return
	}
	if !isExist {
		fmt.Printf("%s not exists!\n", bucketName)
	}
	// 對(duì)象信息
	objectName := "頭像.jpg"
	filePath := "image"
	contentType := "multipart/form-data"
	fPath := filepath.Join(filePath, objectName)
	// 讀取對(duì)象流
	fileInfo, err := os.Stat(fPath)
	if err == os.ErrNotExist {
		log.Printf("%s目標(biāo)文件不存在", fPath)
	}
	f, err := os.Open(fPath)
	if err != nil {
		log.Printf("%s打開目標(biāo)文件", fPath)
		return
	}
	// 上傳文件
	uploadInfo, err := minioClient.PutObject(context.Background(), bucketName,
		objectName, f, fileInfo.Size(),
		minio.PutObjectOptions{ContentType: contentType})
	if err != nil {
		log.Fatalln(err)
		return
	}
	log.Printf("Successfully uploaded %s of size %d\n", objectName, uploadInfo.Size)
}
func CopyObjects(minioClient *minio.Client) {
	// Source object
	srcOpts := minio.CopySrcOptions{
		Bucket: "bucket02",
		Object: "頭像.jpg",
	}
	// Destination object
	dstOpts := minio.CopyDestOptions{
		Bucket: "bucket01",
		Object: "圖片.jpg",
	}
	// copy
	uploadInfo, err := minioClient.CopyObject(context.Background(), dstOpts, srcOpts)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Successfully copied object:", uploadInfo)
}
func StateObjects(minioClient *minio.Client) {
	ObjInfo, err := minioClient.StatObject(context.Background(), "bucket02", "頭像.jpg", minio.StatObjectOptions{})
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("LastModified:%s\tETag:%s\tContentType:%s\tSize:%d\n",
		ObjInfo.LastModified.Format("2006-01-02 03:04:05"),
		ObjInfo.ETag, ObjInfo.ContentType, ObjInfo.Size)
}
func RemoveObject(minioClient *minio.Client) {
	opts := minio.RemoveObjectOptions{}
	err := minioClient.RemoveObject(context.Background(), "bucket01", "圖片.jpg", opts)
	if err != nil {
		fmt.Println(err)
		return
	}
}
func RemoveObjects(minioClient *minio.Client) {
	objectsCh := make(chan minio.ObjectInfo)
	// 注意一般不要自己來構(gòu)造,直接選擇從bucket中查詢,查詢到的對(duì)象放入objectsCh
	for object := range minioClient.ListObjects(context.Background(), "bucket02", minio.ListObjectsOptions{}) {
		if object.Key == "頭像.jpg" {
			objectsCh <- object
		}
	}
	defer close(objectsCh)
	// 刪除
	for rErr := range minioClient.RemoveObjects(context.Background(), "bucket02", objectsCh, minio.RemoveObjectsOptions{}) {
		fmt.Println("Delete err:", rErr.Err.Error())
	}
}
func UploadLargeFileObjects(minioClient *minio.Client) {
	uploadInfo, err := minioClient.FPutObject(context.Background(), "bucket02", "test.csv", "data", minio.PutObjectOptions{
		ContentType: "application/csv",
	})
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Successfully uploaded object: ", uploadInfo)
}
func DownloadLargeFileObjects(minioClient *minio.Client) {
	err := minioClient.FGetObject(context.Background(), "bucket02", "test.csv", "/tmp/myobject", minio.GetObjectOptions{})
	if err != nil {
		fmt.Println(err)
		return
	}
}

到此這篇關(guān)于Golang使用MinIO的文章就介紹到這了,更多相關(guān)Golang使用MinIO內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用GoLang?Fiber進(jìn)行高性能Web開發(fā)實(shí)例詳解

    利用GoLang?Fiber進(jìn)行高性能Web開發(fā)實(shí)例詳解

    這篇文章主要為大家介紹了利用GoLang?Fiber進(jìn)行高性能Web開發(fā)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go語(yǔ)言struct類型詳解

    Go語(yǔ)言struct類型詳解

    這篇文章主要介紹了Go語(yǔ)言struct類型詳解,struct是一種數(shù)據(jù)類型,可以用來定義自己想的數(shù)據(jù)類型,需要的朋友可以參考下
    2014-10-10
  • golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段

    golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段

    這篇文章主要介紹了golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語(yǔ)言性能監(jiān)控和調(diào)優(yōu)的工具和方法

    Go語(yǔ)言性能監(jiān)控和調(diào)優(yōu)的工具和方法

    本文介紹了Go語(yǔ)言性能監(jiān)控和調(diào)優(yōu)的工具和方法,包括?pprof、expvar?和?trace?等工具的使用方法和注意事項(xiàng),以及性能調(diào)優(yōu)的一些常見方法,如減少內(nèi)存分配、避免頻繁的垃圾回收、避免過度查詢數(shù)據(jù)庫(kù)等,針對(duì)不同的程序,應(yīng)該根據(jù)實(shí)際情況采用不同的優(yōu)化方法
    2024-01-01
  • 使用Go語(yǔ)言實(shí)現(xiàn)發(fā)送微信群消息

    使用Go語(yǔ)言實(shí)現(xiàn)發(fā)送微信群消息

    這篇文章主要為大家詳細(xì)介紹了如何使用Go語(yǔ)言實(shí)現(xiàn)發(fā)送微信群消息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Go語(yǔ)言基礎(chǔ)語(yǔ)法之結(jié)構(gòu)體及方法詳解

    Go語(yǔ)言基礎(chǔ)語(yǔ)法之結(jié)構(gòu)體及方法詳解

    結(jié)構(gòu)體類型可以用來保存不同類型的數(shù)據(jù),也可以通過方法的形式來聲明它的行為。本文將介紹go語(yǔ)言中的結(jié)構(gòu)體和方法,以及“繼承”的實(shí)現(xiàn)方法
    2021-09-09
  • Go語(yǔ)言面向?qū)ο笾械亩鄳B(tài)你學(xué)會(huì)了嗎

    Go語(yǔ)言面向?qū)ο笾械亩鄳B(tài)你學(xué)會(huì)了嗎

    面向?qū)ο笾械亩鄳B(tài)(Polymorphism)是指一個(gè)對(duì)象可以具有多種不同的形態(tài)或表現(xiàn)方式,本文將通過一些簡(jiǎn)單的示例為大家講解一下多態(tài)的實(shí)現(xiàn),需要的可以參考下
    2023-07-07
  • GoFrame?ORM原生方法操作示例

    GoFrame?ORM原生方法操作示例

    這篇文章主要為大家介紹了GoFrame?ORM原生方法操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • golang實(shí)戰(zhàn)之truncate日志文件詳解

    golang實(shí)戰(zhàn)之truncate日志文件詳解

    這篇文章主要給大家介紹了關(guān)于golang實(shí)戰(zhàn)之truncate日志文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • Go語(yǔ)言結(jié)合grpc和protobuf實(shí)現(xiàn)去中心化的聊天室

    Go語(yǔ)言結(jié)合grpc和protobuf實(shí)現(xiàn)去中心化的聊天室

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言如何結(jié)合grpc和protobuf實(shí)現(xiàn)去中心化的聊天室,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03

最新評(píng)論