Go语言封装MinIO相关操作详解

 更新时间:2024年11月25日 10:27:35   作者:熬了夜的程序员  
MinIO 是一个高性能的对象存储服务,兼容 Amazon S3 API,广泛用于存储和管理海量数据,本文将介绍如何用 Go 语言封装一个简单的 MinIO 操作包,需要的可以参考下

背景介绍

MinIO 是一个高性能的对象存储服务,兼容 Amazon S3 API,广泛用于存储和管理海量数据。在实际开发中,封装一个便于使用的 MinIO 操作包,可以帮助我们简化操作逻辑,提高代码的可读性和复用性。

本文将介绍如何用 Go 语言封装一个简单的 MinIO 操作包,支持以下功能:

  • 初始化 MinIO 客户端
  • 上传文件
  • 下载文件
  • 列出文件
  • 删除文件
  • 获取文件的预签名 URL

代码实现

结构体定义

package minio_wrapper

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
)

type MinioClient struct {
	client   *minio.Client
	bucket   string
	location string
}

初始化 MinIO 客户端

通过 NewMinioClient 方法,可以根据配置参数初始化 MinIO 客户端,并确保指定的存储桶存在。如果存储桶不存在,会自动创建。

func NewMinioClient(endpoint, accessKeyID, secretAccessKey, bucket, location string, useSSL bool) (*MinioClient, error) {
    client, err := minio.New(endpoint, &minio.Options{
        Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
        Secure: useSSL,
    })
    if err != nil {
        return nil, fmt.Errorf("failed to initialize minio client: %w", err)
    }

    ctx := context.Background()
    exists, err := client.BucketExists(ctx, bucket)
    if err != nil {
        return nil, fmt.Errorf("failed to check bucket existence: %w", err)
    }
    if !exists {
        err = client.MakeBucket(ctx, bucket, minio.MakeBucketOptions{Region: location})
        if err != nil {
            return nil, fmt.Errorf("failed to create bucket: %w", err)
        }
        log.Printf("Successfully created bucket: %s\n", bucket)
    }

    return &MinioClient{
        client:   client,
        bucket:   bucket,
        location: location,
    }, nil
}

上传文件

通过 UploadFile 方法,可以将本地文件上传到指定存储桶中。

func (mc *MinioClient) UploadFile(objectName, filePath, contentType string) error {
    ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    defer cancel()

    _, err := mc.client.FPutObject(ctx, mc.bucket, objectName, filePath, minio.PutObjectOptions{
        ContentType: contentType,
    })
    if err != nil {
        return fmt.Errorf("failed to upload file: %w", err)
    }

    log.Printf("Successfully uploaded %s to bucket %s\n", objectName, mc.bucket)
    return nil
}

下载文件

通过 DownloadFile 方法,可以将存储桶中的文件下载到本地指定路径。

func (mc *MinioClient) DownloadFile(objectName, filePath string) error {
    ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    defer cancel()

    err := mc.client.FGetObject(ctx, mc.bucket, objectName, filePath, minio.GetObjectOptions{})
    if err != nil {
        return fmt.Errorf("failed to download file: %w", err)
    }

    log.Printf("Successfully downloaded %s to %s\n", objectName, filePath)
    return nil
}

列出文件

通过 ListFiles 方法,可以列出存储桶中的所有文件。

func (mc *MinioClient) ListFiles() ([]string, error) {
    ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    defer cancel()

    objectCh := mc.client.ListObjects(ctx, mc.bucket, minio.ListObjectsOptions{})
    var objects []string
    for object := range objectCh {
        if object.Err != nil {
            return nil, fmt.Errorf("error listing object: %w", object.Err)
        }
        objects = append(objects, object.Key)
    }

    return objects, nil
}

删除文件

通过 DeleteFile 方法,可以删除存储桶中的指定文件。

func (mc *MinioClient) DeleteFile(objectName string) error {
    ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    defer cancel()

    err := mc.client.RemoveObject(ctx, mc.bucket, objectName, minio.RemoveObjectOptions{})
    if err != nil {
        return fmt.Errorf("failed to delete file: %w", err)
    }

    log.Printf("Successfully deleted %s from bucket %s\n", objectName, mc.bucket)
    return nil
}

获取文件的预签名 URL

通过 GetFileURL 方法,可以生成文件的预签名 URL,便于临时访问私有文件。

func (mc *MinioClient) GetFileURL(objectName string, expiry time.Duration) (string, error) {
    ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    defer cancel()

    reqParams := make(map[string]string)
    presignedURL, err := mc.client.PresignedGetObject(ctx, mc.bucket, objectName, expiry, reqParams)
    if err != nil {
        return "", fmt.Errorf("failed to generate presigned URL: %w", err)
    }

    log.Printf("Successfully generated URL for %s: %s\n", objectName, presignedURL)
    return presignedURL.String(), nil
}

使用示例

以下是一个完整的使用示例:

package main

import (
    "log"
    "minio_wrapper"
    "time"
)

func main() {
    endpoint := "127.0.0.1:9000"
    accessKeyID := "minioadmin"
    secretAccessKey := "minioadmin"
    bucket := "mybucket"
    location := "us-east-1"
    useSSL := false

    client, err := minio_wrapper.NewMinioClient(endpoint, accessKeyID, secretAccessKey, bucket, location, useSSL)
    if err != nil {
        log.Fatalf("Failed to initialize MinioClient: %v", err)
    }

    // 上传文件
    err = client.UploadFile("example.txt", "/path/to/local/file.txt", "text/plain")
    if err != nil {
        log.Fatalf("Failed to upload file: %v", err)
    }

    // 获取预签名 URL
    url, err := client.GetFileURL("example.txt", time.Hour*1)
    if err != nil {
        log.Fatalf("Failed to get file URL: %v", err)
    }
    log.Printf("Presigned URL: %s", url)
}

总结

通过封装 MinIO 的常用操作,我们可以极大简化代码逻辑,提高开发效率。在实际项目中,可以根据需求进一步扩展功能,例如支持更多的操作、增加日志功能或通过配置文件动态加载参数等。

到此这篇关于Go语言封装MinIO相关操作详解的文章就介绍到这了,更多相关Go封装MinIO内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • golang struct json tag的使用以及深入讲解

    golang struct json tag的使用以及深入讲解

    这篇文章主要给大家介绍了关于golang struct json tag的使用以及深入讲解,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-02-02
  • 在Go中实现和使用堆栈以及先进先出原则详解

    在Go中实现和使用堆栈以及先进先出原则详解

    Go是一种功能强大的编程语言,提供了丰富的数据结构和算法,堆栈是计算机科学中的基本数据结构之一,在本博文中,我们将探讨如何在 Go 中实现和使用堆栈,以及堆栈如何遵循先进先出 (FIFO) 原则
    2023-10-10
  • Golang中的四个括号示例详解

    Golang中的四个括号示例详解

    这篇文章主要介绍了Golang中的四个括号,本文通过实例代码给大家介绍的非常详细,通过实例代码补充介绍了有效的括号golang实现,需要的朋友可以参考下
    2024-03-03
  • GO语言中的Map使用方法详解

    GO语言中的Map使用方法详解

    这篇文章主要给大家介绍了关于GO语言中Map使用方法的相关资料,在go语言中map是散列表的引用,map的类型是map[k]v,也就是常说的k-v键值对,需要的朋友可以参考下
    2023-08-08
  • Go中的字典Map增删改查、排序及其值类型

    Go中的字典Map增删改查、排序及其值类型

    本文详细介绍了Go语言中Map的基本概念、声明初始化、增删改查操作、反转、排序以及如何判断键是否存在等操作,Map是一种基于键值对的无序数据结构,键必须是支持相等运算符的类型,值可以是任意类型,初始化Map时推荐指定容量以提高性能
    2024-09-09
  • go 语言字符类型 byte 与 rune案例详解

    go 语言字符类型 byte 与 rune案例详解

    这篇文章主要介绍了go 语言字符类型 byte 与 rune案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Go关键字defer的使用和底层实现

    Go关键字defer的使用和底层实现

    defer是Go语言的关键字,一般用于资源的释放和异常的捕捉,defer语句后将其后面跟随的语句进行延迟处理,就是说在函数执行完毕后再执行调用,也就是return的ret指令之前,本文给大家介绍了Go关键字defer的使用和底层实现,需要的朋友可以参考下
    2023-11-11
  • go语言template用法实例

    go语言template用法实例

    这篇文章主要介绍了go语言template用法,实例分析了template的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go初学者踩坑之go mod init与自定义包的使用

    Go初学者踩坑之go mod init与自定义包的使用

    go mod是go的一个模块管理工具,用来代替传统的GOPATH方案,下面这篇文章主要给大家介绍了关于Go初学者踩坑之go mod init与自定义包的使用,需要的朋友可以参考下
    2022-10-10
  • go redis实现滑动窗口限流的方式(redis版)

    go redis实现滑动窗口限流的方式(redis版)

    这篇文章主要介绍了go redis实现滑动窗口限流的方式(redis版),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12

最新评论