MinIO设置桶权限

MinIO设置桶权限

简介

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。

创建桶

/**
     * 初始化Bucket
     *
     * @throws Exception 异常
     */
    @SneakyThrows
    private static void createBucket()
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        if (!minioClient.bucketExists( BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket( MakeBucketArgs.builder().bucket(bucketName).build());
            //设置桶策略
            setBucketPolicy(bucketName);
        }
    }

创建桶成功后,默认的policy是私有的private,如果想要更改这个权限可以通过页面直接修改或者通过minio-api修改,通过api需要用到setBucketPolicy接口

获取桶权限

/**
     * 获取存储桶策略
     *
     * @param bucketName 存储桶名称
     * @return json
     */
    @SneakyThrows
    private static JSONObject getBucketPolicy(String bucketName)
        throws IOException, InvalidKeyException, InvalidResponseException, BucketPolicyTooLargeException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InsufficientDataException, ErrorResponseException {
        String bucketPolicy = minioClient
            .getBucketPolicy( GetBucketPolicyArgs.builder().bucket(bucketName).build());
        return JSONObject.parseObject(bucketPolicy);
    }

设置桶权限

 /**
     * 设置桶策存储策略为public
     *
     * @param bucketName 存储桶名称
     */
    private static void setBucketPolicy(String bucketName) {
        // Define the policy string
           String policy ="{" +
               "\"Version\":\"2012-10-17\"," +
               "\"Statement\":[" +
               "              {\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"," +
               "                           \"s3:ListBucketMultipartUploads\"]," +
               "               \"Resource\":[\"arn:aws:s3:::"+ bucketName +"\"]," +
               "               \"Effect\":\"Allow\"," +
               "               \"Principal\":{\"AWS\":[\"*\"]}" +
               "              }," +
               "             {\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\"," +
               "                          \"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"]," +
               "              \"Resource\":[\"arn:aws:s3:::"+ bucketName +"/*\"]," +
               "              \"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]}}" +
               "           ]" +
               "}";
        try {
            minioClient.setBucketPolicy( bucketName,policy);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        } catch (InvalidBucketNameException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (ServerException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        }

    }

完整的MinioUtil工具类(包括文件分片上传大文件)

package com.ruoyi.system.minio;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.bo.SysOssConfigBo;
import com.ruoyi.system.domain.vo.SysOssConfigVo;
import com.ruoyi.system.service.ISysOssConfigService;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.SneakyThrows;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
public class MinioUtil {
    static Logger log = LoggerFactory.getLogger( MinioUtil.class);
    private static MinioClient minioClient;
    private static String endpoint;
    private static String bucketName ;
    private static String accessKey ;
    private static String secretKey ;
    @Value("${minio.url}")
    private  String endpoint1;
    @Value("${minio.bucket-name}")
    private  String bucketName1 ;
    @Value("${minio.access-key}")
    private  String accessKey1 ;
    @Value("${minio.secret-key}")
    private  String secretKey1 ;
    public static String getEndpoint() {
        return endpoint;
    }

    public static String getBucketName() {
        return bucketName;
    }

    public static String getAccessKey() {
        return accessKey;
    }

    public static String getSecretKey() {
        return secretKey;
    }

    private static final String SEPARATOR = "/";

    private static final String TEMPBUCKET = "temp";


    private static ISysOssConfigService iSysOssConfigService;

    @Autowired
    public void setiSysOssConfigService(ISysOssConfigService iSysOssConfigService){
        MinioUtil.iSysOssConfigService = iSysOssConfigService;
    }
    /**
     * 创建minioClient
     * @return
     */

//    @PostConstruct
//    public static void init() {
//        createMinioClient();
//    }
    public static MinioClient createMinioClient() {
        try {
            if (null == minioClient) {
                log.info("minioClient create start");

                minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey)
                    .build();
                //创建存储桶
                createBucket(bucketName);
                //创建临时桶
                createBucket(TEMPBUCKET);
                log.info("minioClient create end");
                //更新sys_oss_config
                SysOssConfigBo sysOssConfigBo = new SysOssConfigBo();
                sysOssConfigBo.setConfigKey("minio");
                TableDataInfo<SysOssConfigVo> sysOssConfigVoTableDataInfo = iSysOssConfigService.queryPageList(sysOssConfigBo, new PageQuery());
                List<SysOssConfigVo> rows = sysOssConfigVoTableDataInfo.getRows();
                if(rows.size()> 0){
                    //更新
                    sysOssConfigBo.setOssConfigId(rows.get(0).getOssConfigId());
                    sysOssConfigBo.setAccessKey(accessKey);
                    sysOssConfigBo.setSecretKey(secretKey);
                    sysOssConfigBo.setBucketName(bucketName);
                    sysOssConfigBo.setEndpoint(endpoint.replaceAll("http://",""));
                    sysOssConfigBo.setIsHttps("N");
                    sysOssConfigBo.setStatus("0");
                    iSysOssConfigService.updateByBo(sysOssConfigBo);
                }else{
                    //新增
                    sysOssConfigBo.setAccessKey(accessKey);
                    sysOssConfigBo.setSecretKey(secretKey);
                    sysOssConfigBo.setBucketName(bucketName);
                    sysOssConfigBo.setEndpoint(endpoint.replaceAll("http://",""));
                    sysOssConfigBo.setIsHttps("N");
                    sysOssConfigBo.setStatus("0");
                    iSysOssConfigService.insertByBo(sysOssConfigBo);
                }

            }
        } catch (Exception e) {
            log.error("连接MinIO服务器异常:{}", e);
        }
        return minioClient;
    }

    /**
     * 获取上传文件的基础路径
     *
     * @return url
     */
    public static String getBasisUrl() {
//        return endpoint + SEPARATOR + bucketName + SEPARATOR;
        return  bucketName + SEPARATOR;
    }

    /**
     * 初始化Bucket
     *
     * @throws Exception 异常
     */
    @SneakyThrows
    private static void createBucket()
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        if (!minioClient.bucketExists( BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket( MakeBucketArgs.builder().bucket(bucketName).build());
            //设置桶策略
            setBucketPolicy(bucketName);
        }
    }

    /**
     * 验证bucketName是否存在
     *
     * @return boolean true:存在
     */
    @SneakyThrows
    public static boolean bucketExists()
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }

    /**
     * 创建bucket
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public static void createBucket(String bucketName)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            //设置桶策略
            setBucketPolicy(bucketName);
        }
    }

    /**
     * 获取存储桶策略
     *
     * @param bucketName 存储桶名称
     * @return json
     */
    @SneakyThrows
    private static JSONObject getBucketPolicy(String bucketName)
        throws IOException, InvalidKeyException, InvalidResponseException, BucketPolicyTooLargeException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InsufficientDataException, ErrorResponseException {
        String bucketPolicy = minioClient
            .getBucketPolicy( GetBucketPolicyArgs.builder().bucket(bucketName).build());
        return JSONObject.parseObject(bucketPolicy);
    }

    /**
     * 设置桶策存储策略为public
     *
     * @param bucketName 存储桶名称
     */
    private static void setBucketPolicy(String bucketName) {
        // Define the policy string
           String policy ="{" +
               "\"Version\":\"2012-10-17\"," +
               "\"Statement\":[" +
               "              {\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"," +
               "                           \"s3:ListBucketMultipartUploads\"]," +
               "               \"Resource\":[\"arn:aws:s3:::"+ bucketName +"\"]," +
               "               \"Effect\":\"Allow\"," +
               "               \"Principal\":{\"AWS\":[\"*\"]}" +
               "              }," +
               "             {\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\"," +
               "                          \"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"]," +
               "              \"Resource\":[\"arn:aws:s3:::"+ bucketName +"/*\"]," +
               "              \"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]}}" +
               "           ]" +
               "}";
        try {
            minioClient.setBucketPolicy( bucketName,policy);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        } catch (InvalidBucketNameException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (ServerException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 获取全部bucket
     * <p>
     * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
     */
    @SneakyThrows
    public static List<Bucket> getAllBuckets()
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.listBuckets();
    }

    /**
     * 根据bucketName获取信息
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public static Optional<Bucket> getBucket(String bucketName)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }

    /**
     * 根据bucketName删除信息
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public static void removeBucket(String bucketName)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
    }


    /**
     * 判断文件是否存在
     *
     * @param bucketName 存储桶
     * @param objectName 对象
     * @return true:存在
     */
    @SneakyThrows
    public static boolean doesObjectExist(String bucketName, String objectName) {
        boolean exist = true;
        try {
            minioClient
                .statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            exist = false;
        }
        return exist;
    }

    /**
     * 判断文件夹是否存在
     *
     * @param bucketName 存储桶
     * @param objectName 文件夹名称(去掉/)
     * @return true:存在
     */
    @SneakyThrows
    public static boolean doesFolderExist(String bucketName, String objectName) {
        boolean exist = false;
        try {
            Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
            for (Result<Item> result : results) {
                Item item = result.get();
                if (item.isDir() && objectName.equals(item.objectName())) {
                    exist = true;
                }
            }
        } catch (Exception e) {
            exist = false;
        }
        return exist;
    }

    /**
     * 根据文件前置查询文件
     *
     * @param bucketName bucket名称
     * @param prefix 前缀
     * @param recursive 是否递归查询
     * @return MinioItem 列表
     */
    @SneakyThrows
    public static List<Item> getAllObjectsByPrefix(String bucketName, String prefix,
                                                   boolean recursive)
        throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException,
        IOException, NoSuchAlgorithmException, ServerException, XmlParserException {
        List<Item> list = new ArrayList<>();
        Iterable<Result<Item>> objectsIterator = minioClient.listObjects(
            ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
        if (objectsIterator != null) {
            for (Result<Item> o : objectsIterator) {
                Item item = o.get();
                list.add(item);
            }
        }
        return list;
    }

    /**
     * 获取文件流
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @return 二进制流
     */
    @SneakyThrows
    public static InputStream getObject(String bucketName, String objectName)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient
            .getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    /**
     * 断点下载
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param offset 起始字节的位置
     * @param length 要读取的长度
     * @return 流
     */
    @SneakyThrows
    public static InputStream getObject(String bucketName, String objectName, long offset, long length)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.getObject(
            GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length)
                .build());
    }

    /**
     * 获取路径下文件列表
     *
     * @param bucketName bucket名称
     * @param prefix 文件名称
     * @param recursive 是否递归查找,如果是false,就模拟文件夹结构查找
     * @return 二进制流
     */
    @SneakyThrows
    public static Iterable<Result<Item>> listObjects(String bucketName, String prefix,
                                                     boolean recursive) {
        return minioClient.listObjects(
            ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
    }

    /**
     * 通过MultipartFile,上传文件
     *
     * @param bucketName 存储桶
     * @param file 文件
     * @param objectName 对象名
     */
    @SneakyThrows
    public static String putObject(String bucketName, MultipartFile file,
                                   String objectName, String contentType){
        InputStream inputStream = file.getInputStream();
        ObjectWriteResponse objectWriteResponse = minioClient.putObject(
            PutObjectArgs.builder().bucket(bucketName).object(objectName)
                .contentType(contentType)
                .stream(
                    inputStream, inputStream.available(), -1)
                .build());

        return bucketName+SEPARATOR+objectWriteResponse.object();
    }

    /**
     *
     * @param file         文件
     * @param sliceIndex  分片索引
     * @param totalPieces 切片总数
     * @param md5         整体文件MD5
     * @return
     * @throws Exception
     */
    public static int uploadBigFileCore(MultipartFile file,
                                 Integer sliceIndex,
                                 Integer totalPieces,
                                 String md5) throws Exception {
        // 检查还需要上传的文件序号
        Iterable<Result<Item>> results = minioClient.listObjects(
            ListObjectsArgs.builder().bucket(TEMPBUCKET).prefix(md5.concat("/")).build());
        Set<String> objectNames = Sets.newHashSet();
        for (Result<Item> item : results) {
            objectNames.add(item.get().objectName());
        }
        List<Integer> indexs = Stream.iterate(0, i -> ++i)
            .limit(totalPieces)
            .filter(i -> !objectNames.contains(md5.concat("/").concat(Integer.toString(i))))
            .sorted()
            .collect(Collectors.toList());
        // 返回需要上传的文件序号,-1是上传完成
        if (indexs.size() > 0) {
            if (!indexs.get(0).equals(sliceIndex)) {
                return indexs.get(0);
            }
        } else {
            return -1;
        }
        // 写入文件
        minioClient.putObject(
            PutObjectArgs.builder()
                .bucket(TEMPBUCKET)
                .object(md5.concat("/").concat(Integer.toString(sliceIndex)))
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(file.getContentType())
                .build());
        if (sliceIndex < totalPieces - 1) {
            return ++sliceIndex;
        } else {
            return -1;
        }
    }

    /**
     * 分片上传
     * @param file    文件
     * @param md5     整体文件MD5
     * @param totalPieces 切片总数
     * @param sliceIndex 分片索引
     * @return
     */
    public static JSONObject uploadBigFile(MultipartFile file) {
        JSONObject jsonObject = new JSONObject();
        try {
            // 分片上传
            String md5 = request.getParameter("md5");
            int totalPieces = Integer.parseInt(request.getParameter("totalPieces"));
            Integer sliceIndex = Integer.valueOf(request.getParameter("sliceIndex"));
            String fileName = request.getParameter("fileName");
            int index = uploadBigFileCore(file, sliceIndex, totalPieces, md5);
            if (index == -1) {
                // 完成上传从缓存目录合并迁移到正式目录
                List<ComposeSource> sourceObjectList = Stream.iterate(0, i -> ++i)
                    .limit(totalPieces)
                    .map(i -> ComposeSource.builder()
                        .bucket(TEMPBUCKET)
                        .object(md5.concat("/").concat(Integer.toString(i)))
                        .build())
                    .collect(Collectors.toList());
                fileName = fileName.substring(0,fileName.lastIndexOf("."))
                    +System.currentTimeMillis()+fileName.substring(fileName.lastIndexOf("."));
                ObjectWriteResponse response = minioClient.composeObject(
                    ComposeObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .sources(sourceObjectList)
                        .build());

                // 删除所有的分片文件
                List<DeleteObject> delObjects = Stream.iterate(0, i -> ++i)
                    .limit(totalPieces)
                    .map(i -> new DeleteObject(md5.concat("/").concat(Integer.toString(i))))
                    .collect(Collectors.toList());
                Iterable<Result<DeleteError>> results =
                    minioClient.removeObjects(
                        RemoveObjectsArgs.builder().bucket(TEMPBUCKET).objects(delObjects).build());
                for (Result<DeleteError> result : results) {
                    DeleteError error = result.get();
                    System.out.println(
                        "Error in deleting object " + error.objectName() + "; " + error.message());
                }

                // 验证md5
                try (InputStream stream = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(response.bucket())
                    .object(response.object())
                    .build())) {
                    String md5Hex = DigestUtils.md5Hex(stream);
                    if (!md5Hex.equals(md5)) {
                        jsonObject.put("fileName",fileName);
                        jsonObject.put("picPath",bucketName+"/"+fileName);
                        return jsonObject;
                    }
                }
                System.out.println("完成上传,保存文件信息到数据库");
            }
            System.out.println("返回数据:" + index);
            jsonObject.put("index",index);
            return jsonObject;
        } catch (Exception e) {
            e.printStackTrace();
        }
        jsonObject.put("index","fail");
        return jsonObject;
    }

    /**
     * 上传本地文件
     *
     * @param bucketName 存储桶
     * @param objectName 对象名称
     * @param fileName 本地文件路径
     */
    @SneakyThrows
    public static ObjectWriteResponse putObject(String bucketName, String objectName,
                                                String fileName,String contentType)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.uploadObject(
            UploadObjectArgs.builder()
                .bucket(bucketName).object(objectName)
                .contentType(contentType)
                .filename(fileName).build());
    }

    /**
     * 通过流上传文件
     *
     * @param bucketName 存储桶
     * @param objectName 文件对象
     * @param inputStream 文件流
     */
    @SneakyThrows
    public static ObjectWriteResponse putObject(String bucketName, String objectName,String contentType,
                                                InputStream inputStream)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.putObject(
            PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
                inputStream, inputStream.available(), -1)
                .contentType(contentType)
                .build());
    }

    /**
     * 创建文件夹或目录
     *
     * @param bucketName 存储桶
     * @param objectName 目录路径
     */
    @SneakyThrows
    public static ObjectWriteResponse putDirObject(String bucketName, String objectName)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.putObject(
            PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
                new ByteArrayInputStream(new byte[]{}), 0, -1)
                .build());
    }

    /**
     * 拷贝文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param srcBucketName 目标bucket名称
     * @param srcObjectName 目标文件名称
     */
    @SneakyThrows
    public static ObjectWriteResponse copyObject(String bucketName, String objectName,
                                                 String srcBucketName, String srcObjectName)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        return minioClient.copyObject(
            CopyObjectArgs.builder()
                .source(CopySource.builder().bucket(bucketName).object(objectName).build())
                .bucket(srcBucketName)
                .object(srcObjectName)
                .build());
    }

    /**
     * 删除文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     */
    @SneakyThrows
    public static void removeObject(String bucketName, String objectName)
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        minioClient
            .removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    @SneakyThrows
    public static Iterable<Result<DeleteError>>  removeObjects(Integer totalPieces,String md5){
        // 删除所有的分片文件
        List<DeleteObject> delObjects = Stream.iterate(0, i -> ++i)
            .limit(totalPieces)
            .map(i -> new DeleteObject(md5.concat("/").concat(Integer.toString(i))))
            .collect(Collectors.toList());
        Iterable<Result<DeleteError>> results =
            minioClient.removeObjects(
                RemoveObjectsArgs.builder().bucket(TEMPBUCKET).objects(delObjects).build());
        return results;
    }

    /**
     * 批量删除文件
     *
     * @param bucketName bucket
     * @param keys 需要删除的文件列表
     * @return
     */
    public static void removeObjects(String bucketName, List<String> keys) {
        List<DeleteObject> objects = new LinkedList<>();
        keys.forEach(s -> {
            objects.add(new DeleteObject(s));
            try {
                removeObject(bucketName, s);
            } catch (Exception e) {
                log.error("批量删除失败!error:{}",e);
            }
        });
    }


    /**
     * 获取文件外链
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param expires 过期时间 <=7 秒级
     * @return url
     */
    @SneakyThrows
    public static String getPresignedObjectUrl(String bucketName, String objectName,
                                               Integer expires, TimeUnit timeUnit) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expires,timeUnit).method( Method.GET).build();
        return minioClient.getPresignedObjectUrl(getPresignedObjectUrlArgs);
    }

    /**
     * 给presigned URL设置策略
     *
     * @param bucketName 存储桶
     * @param objectName 对象名
    //     * @param expires 过期策略
     * @return map
     */
    @SneakyThrows
    public static String getPresignedObjectUrl(String bucketName, String objectName
    )
        throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, ServerException, InternalException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
        GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).method(Method.GET).build();
        return minioClient.getPresignedObjectUrl(getPresignedObjectUrlArgs);
    }

    @SneakyThrows
    public static void getObject(HttpServletResponse httpServletResponse, String filePath) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        String fileName = getFileName(filePath);
        InputStream inputStream = minioClient.getObject(GetObjectArgs.builder()
            .bucket(bucketName)
            .object(fileName)
            .build());
        downloadFile(httpServletResponse, inputStream, fileName);
    }

    /**
     * 下载文件
     *
     * @param httpServletResponse httpServletResponse
     * @param inputStream         inputStream
     * @param fileName            文件名
     * @throws IOException IOException
     */
    public static void downloadFile(HttpServletResponse httpServletResponse, InputStream inputStream, String fileName) throws IOException {
        //设置响应头信息,告诉前端浏览器下载文件
        httpServletResponse.setContentType("application/octet-stream;charset=UTF-8");
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        //获取输出流进行写入数据
        OutputStream outputStream = httpServletResponse.getOutputStream();
        // 将输入流复制到输出流
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        // 关闭流资源
        inputStream.close();
        outputStream.close();
    }

    /**
     * 根据文件路径获取文件名称
     *
     * @param filePath 文件路径
     * @return 文件名
     */
    public static String getFileName(String filePath) {
        String[] split = StringUtils.split(filePath, "/");
        return split[split.length - 1];
    }

    /**
     * 将URLDecoder编码转成UTF8
     *
     * @param str
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {
        String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
        return URLDecoder.decode(url, "UTF-8");
    }
    public static void setEndpoint(String endpoint) {
        MinioUtil.endpoint = endpoint;
    }
    public static void setBucketName(String bucketName) {
        MinioUtil.bucketName = bucketName;
    }
    public static void setAccessKey(String accessKey) {
        MinioUtil.accessKey = accessKey;
    }
    public static void setSecretKey(String secretKey) {
        MinioUtil.secretKey = secretKey;
    }


    @PostConstruct
    public void init()  {
        endpoint = endpoint1;
        accessKey = accessKey1;
        secretKey = secretKey1;
        bucketName = bucketName1;
        createMinioClient();
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值