美文网首页golang 编程笔记
【golang】minio文件服务器使用教程

【golang】minio文件服务器使用教程

作者: dongzd | 来源:发表于2020-07-16 11:25 被阅读0次

    项目中需要大量用到从文件服务器获取文件,为了减少一丁点内存的复用,使用了基本的sync.pool,具体代码如下:

    var defaultBucketName = "worker"
    var defaultLocation = "us-east-1"
    
    var minioServerPool *sync.Pool
    
    func init() {
        minioServerPool = &sync.Pool{
            New: func() interface{} {
                return &MinioServe{}
            },
        }
    }
    
    type MinioBucket struct {
        BucketName string
        Location   string
    }
    
    type MinioFileObject struct {
        ObjectName  string
        FilePath    string
        ContentType string
        Bucket      MinioBucket
        Config      MinioConfig
    }
    
    type MinioConfig struct {
        EndPoint        string `json:"endpoint"`
        AccessKeyID     string `json:"accessKeyId"`
        SecretAccessKey string `json:"secretAccessKey"`
        UseSSL          bool   `json:"useSSL"`
    }
    
    func (c *MinioConfig) Validate() error {
        if c.EndPoint == "" {
            return errors.New("endpoint is not specified")
        }
        if c.AccessKeyID == "" {
            return errors.New("accessKeyId is not specified")
        }
        if c.SecretAccessKey == "" {
            return errors.New("secretAccessKey is not specified")
        }
        return nil
    }
    
    func (c *MinioConfig) GetClient() (*minio.Client, error) {
        if err := c.Validate(); err != nil {
            return nil, err
        }
        client, err := minio.New(c.EndPoint, c.AccessKeyID, c.SecretAccessKey, c.UseSSL)
        if err != nil {
            return nil, err
        }
        return client, nil
    }
    
    type MinioServerOption func(*MinioServe)
    
    func WithMinioServerClient(c *minio.Client) MinioServerOption {
        return func(s *MinioServe) {
            s.Client = c
        }
    }
    
    type MinioServe struct {
        Client *minio.Client
    }
    
    func NewMinioServer(opts ...MinioServerOption) (*MinioServe, error) {
    
        m := &MinioServe{}
        for _, opt := range opts {
            opt(m)
        }
        return m, nil
    }
    
    func (m *MinioServe) Reset() {
        m.Client = nil
    }
    
    func (m *MinioServe) createBucket(name string, loc string) (bool, error) {
        // 判断桶是否存在
        exists, err := m.Client.BucketExists(name)
        if err == nil && exists {
            return true, nil
        }
        // 创建新桶
        err = m.Client.MakeBucket(name, loc)
        if err != nil {
            return false, err
        }
        return true, nil
    }
    
    func (m *MinioServe) FileUpload(obj *MinioFileObject) (int64, error) {
        _, err := m.createBucket(obj.Bucket.BucketName, obj.Bucket.Location)
        if err != nil {
            return 0, err
        }
        n, err := m.Client.FPutObject(obj.Bucket.BucketName, obj.ObjectName, obj.FilePath, minio.PutObjectOptions{ContentType: obj.ContentType})
        if err != nil {
            return 0, err
        }
        return n, nil
    }
    
    func (m *MinioServe) FileDownloadToList(obj *MinioFileObject) ([]string, error) {
        res := make([]string, 0)
        ctx, cancel := context.WithTimeout(context.Background(), 200*time.Second)
        defer cancel()
        file, err := m.Client.GetObjectWithContext(ctx, obj.Bucket.BucketName, obj.ObjectName, minio.GetObjectOptions{})
        if err != nil {
            return res, err
        }
        defer file.Close()
        reader := bufio.NewReader(file)
        for {
            data, _, err := reader.ReadLine()
            if err != nil {
                if err == io.EOF {
                    break
                } else {
                    return res, err
                }
            }
            res = append(res, string(data))
        }
        return res, nil
    }
    
    func (m *MinioServe) FileDownloadToDic(obj *MinioFileObject) (string, error) {
        ctx, cancel := context.WithTimeout(context.Background(), 200*time.Second)
        defer cancel()
        file, err := m.Client.GetObjectWithContext(ctx, obj.Bucket.BucketName, obj.ObjectName, minio.GetObjectOptions{})
        if err != nil {
            return "", err
        }
        defer file.Close()
        name := filepath.Base(obj.ObjectName)
        if util.FileExists(name) {
            log.Printf("[minio] %s already exists", name)
            return name, nil
        }
    
        locatFile, err := os.Create(fmt.Sprintf("%s", name))
    
        if err != nil {
            return "", err
        }
        defer locatFile.Close()
        _, err = io.Copy(locatFile, file)
        if err != nil {
            return "", err
        }
    
        return name, nil
    }
    
    func acquireMinioServer() *MinioServe {
        return minioServerPool.Get().(*MinioServe)
    }
    
    func releaseMinioServer(m *MinioServe) {
        m.Reset()
        minioServerPool.Put(m)
    
    }
    
    func FileUpload(obj *MinioFileObject) (int64, error) {
    
        m := acquireMinioServer()
        client, err := obj.Config.GetClient()
        if err != nil {
            return 0, err
        }
        m.Client = client
        n, err := m.FileUpload(obj)
        if err != nil {
            return 0, err
        }
        releaseMinioServer(m)
        log.Printf("[minio] file upload successed")
        return n, nil
    }
    
    func FileDownloadToList(obj *MinioFileObject) ([]string, error) {
    
        m := acquireMinioServer()
        client, err := obj.Config.GetClient()
        if err != nil {
            return nil, err
        }
        defer func() {
            releaseMinioServer(m)
        }()
        m.Client = client
        res, err := m.FileDownloadToList(obj)
        if err != nil {
            return res, err
        }
        log.Printf("[minio] file download successed")
        return res, nil
    }
    
    func FileDownloadToDic(obj *MinioFileObject) (string, error) {
    
        m := acquireMinioServer()
        client, err := obj.Config.GetClient()
        if err != nil {
            return "", err
        }
        defer func() {
            releaseMinioServer(m)
        }()
    
        m.Client = client
        name, err := m.FileDownloadToDic(obj)
        if err != nil {
            return name, err
        }
        log.Printf("[minio] file download successed")
        return name, nil
    }
    

    相关文章

      网友评论

        本文标题:【golang】minio文件服务器使用教程

        本文链接:https://www.haomeiwen.com/subject/tfhphktx.html