MinIo对象存储文件上传,下载,预览,批量上传,创建桶等

MinIo 操作工具类

MinIo 旧中文文档

MinIo 英文文档

MinIo 官网地址 https://min.io/

package com.ming.utils;

import io.minio.*;
import io.minio.Result;
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 javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Description minio 单例模式 工具类型、
 * Create By Mr.Fang
 *
 * @time 2022/7/10 9:57
 **/
public class MinioUtils {

    private static MinioUtils minioUtils = new MinioUtils();

    private MinioClient minioClient;

    private static final String endpoint = "http://xxx.xxx.xxx.xx:9000";
    private static final String accessKey = "xxxxxx"; // 你的 key
    private static final String secretKey = "xxxxxxxxxxxx"; //你的 secret
    private String bucketName = "xxxx"; //桶名称

    private MinioUtils() {
        this.init();
    }

    /**
     * 初始化创建对象
     */
    private void init() {
        minioClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey).build();
    }


    /**
     * Description  获取 MinioUtils 对象
     * Create By Mr.Fang
     *
     * @return com.ming.utils.MinioUtils
     * @time 2022/7/10 10:18
     **/
    public static MinioUtils getInstance() {

        return minioUtils;
    }

    /**
     * Description  获取 MinioClient 对象
     * Create By Mr.Fang
     *
     * @return com.ming.utils.MinioUtils
     * @time 2022/7/10 10:18
     **/
    public MinioClient getMinioClient() {
        return minioClient;
    }

    /**
     * 设置 桶名称
     *
     * @param bucketName
     */
    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }

    /**
     * Description 判断桶是否存在
     * Create By Mr.Fang
     *
     * @param bucket
     * @return java.lang.Boolean
     * @time 2022/7/10 9:57
     **/
    public Boolean existBucket(String bucket) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Description 创建一个桶
     * Create By Mr.Fang
     *
     * @param bucket 桶名称
     * @return java.lang.Boolean
     * @time 2022/7/10 9:56
     **/
    public Boolean createBucket(String bucket) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * Description 上传本地文件
     * Create By Mr.Fang
     *
     * @param path   本地文件路径
     * @param object 文件名
     * @return java.lang.Boolean
     * @time 2022/7/10 9:55
     **/
    public Boolean uploadObject(String path, String object) {
        try {
            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket(bucketName)
                            .object(object)
                            .filename(path)
                            .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * Description 以流的方式上传文件
     * Create By Mr.Fang
     *
     * @param in     input 流
     * @param object 文件名
     * @param size   文件大小
     * @return java.lang.Boolean
     * @time 2022/7/10 9:55
     **/
    public Boolean uploadObject(InputStream in, String object, Long size) {
        try {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(object)
                            .stream(in, size, -1)
                            .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * Description  多文件上传
     * Create By Mr.Fang
     *
     * @param objects SnowballObject对象
     * @return java.lang.Boolean
     * @Param
     * @time 2022/7/10 10:24
     **/
    public Boolean uploadsObject(List<SnowballObject> objects) {
        try {
            minioClient.uploadSnowballObjects(
                    UploadSnowballObjectsArgs.builder().bucket(bucketName).objects(objects).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * Description 批量删除文件对象
     * Create By Mr.Fang
     *
     * @param objects 文件名称或完整文件路径
     * @return java.util.List<io.minio.messages.DeleteError>
     * @time 2022/7/10 9:54
     **/
    public List<DeleteError> deleteObject(List<String> objects) {
        List<DeleteError> deleteErrors = new ArrayList<>();
        List<DeleteObject> deleteObjects = objects.stream().map(value -> new DeleteObject(value)).collect(Collectors.toList());
        Iterable<Result<DeleteError>> results =
                minioClient.removeObjects(
                        RemoveObjectsArgs
                                .builder()
                                .bucket(bucketName)
                                .objects(deleteObjects)
                                .build());
        try {
            for (Result<DeleteError> result : results) {
                DeleteError error = result.get();
                deleteErrors.add(error);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return deleteErrors;
    }

    /**
     * Description  下载文件到本地
     * Create By Mr.Fang
     *
     * @param object 文件名
     * @param output 输出路径
     * @return void
     * @time 2022/7/10 9:53
     **/
    public void download(String object, String output) {

        try {
            minioClient.downloadObject(
                    DownloadObjectArgs.builder()
                            .bucket(bucketName)
                            .object(object)
                            .filename(output)
                            .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * Description 下载 minio文件,返回流的方式,同时支持在线预览
     * Create By Mr.Fang
     *
     * @param object   文件名称
     * @param isOnline 是否在线预览,不同文件类型请修改 setContentType
     * @param response 响应对象
     * @return void
     * @time 2022/7/10 9:51
     **/
    public void download(String object, Boolean isOnline, HttpServletResponse response) {
        try (InputStream stream = minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(object)
                        .build())) {
            try {
                BufferedInputStream br = new BufferedInputStream(stream);
                byte[] buf = new byte[1024];
                int len = 0;
                response.reset(); // 非常重要
                if (Objects.nonNull(isOnline) && isOnline) { // 在线打开方式
                    response.setContentType("application/pdf");
                    response.setHeader("Content-Disposition", "inline; filename=" + object);
                } else { // 纯下载方式
                    response.setContentType("application/x-msdownload");
                    response.setHeader("Content-Disposition", "attachment; filename=" + object);
                }
                OutputStream out = response.getOutputStream();
                while ((len = br.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.flush();
                br.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * Description 获取所有桶
     * Create By Mr.Fang
     *
     * @return java.util.List<io.minio.messages.Bucket>
     * @time 2022/7/10 9:50
     **/
    public List<Bucket> listBuckets() {

        try {
            return minioClient.listBuckets();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Description 文件列表
     * Create By Mr.Fang
     *
     * @param limit 范围 1-1000
     * @return java.util.List<io.minio.messages.Item>
     * @time 2022/7/10 9:50
     **/
    public List<Item> listObjects(int limit) {
        List<Item> objects = new ArrayList<>();
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .maxKeys(limit)
                        .includeVersions(true)
                        .build());
        try {
            for (Result<Item> result : results) {
                objects.add(result.get());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objects;
    }

    /**
     * Description 生成预览链接,最大7天有效期;
     * 如果想永久有效,在 minio 控制台设置仓库访问规则总几率
     * Create by Mr.Fang
     *
     * @param object      文件名称
     * @param contentType 预览类型 image/gif", "image/jpeg", "image/jpg", "image/png", "application/pdf
     * @return java.lang.String
     * @Time 9:43 2022/7/10
     * @Params
     **/
    public String getPreviewUrl(String object, String contentType) {
        Map<String, String> reqParams = new HashMap<>();
        reqParams.put("response-content-type", contentType != null ? contentType : "application/pdf");
        String url = null;
        try {
            url = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(object)
                            .expiry(7, TimeUnit.DAYS)
                            .extraQueryParams(reqParams)
                            .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url;
    }

    /**
     * Description 网络文件转储 minio
     * Author Mr.Fang
     *
     * @param httpUrl 文件地址
     * @return void
     * @Time 9:42 2022/7/10
     * @Params
     **/
    public void netToMinio(String httpUrl) {
        int i = httpUrl.lastIndexOf(".");
        String substring = httpUrl.substring(i);
        URL url;
        try {
            url = new URL(httpUrl);
            URLConnection urlConnection = url.openConnection();
            // agent 模拟浏览器
            urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
            DataInputStream dataInputStream = new DataInputStream(url.openStream());

            // 临时文件转储
            File tempFile = File.createTempFile(UUID.randomUUID().toString().replace("-", ""), substring);
            FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = dataInputStream.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            fileOutputStream.write(output.toByteArray());
            // 上传minio
            uploadObject(tempFile.getAbsolutePath(), tempFile.getName());
            dataInputStream.close();
            fileOutputStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Description 文件转字节数组
     * Create By Mr.Fang
     *
     * @param path 文件路径
     * @return byte[] 字节数组
     * @time 2022/7/10 10:55
     **/
    public byte[] fileToBytes(String path) {
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            bos = new ByteArrayOutputStream();
            fis = new FileInputStream(path);
            int temp;
            byte[] bt = new byte[1024 * 10];
            while ((temp = fis.read(bt)) != -1) {
                bos.write(bt, 0, temp);
            }
            bos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (Objects.nonNull(fis)) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bos.toByteArray();
    }

    public static void main(String[] args) throws Exception {
        MinioUtils minioUtils = MinioUtils.getInstance();
        // 多文件上传示例
        List<SnowballObject> objects = new ArrayList<>();
        byte[] bytes1 = minioUtils.fileToBytes("C:\\Users\\Administrator\\Desktop\\素材\\1.png");
        byte[] bytes2 = minioUtils.fileToBytes("C:\\Users\\Administrator\\Desktop\\素材\\2.png");
        byte[] bytes3 = minioUtils.fileToBytes("C:\\Users\\Administrator\\Desktop\\素材\\3.png");
        objects.add(new SnowballObject("1.png", new ByteArrayInputStream(bytes1), bytes1.length, ZonedDateTime.now()));
        objects.add(new SnowballObject("2.png", new ByteArrayInputStream(bytes2), bytes2.length, ZonedDateTime.now()));
        objects.add(new SnowballObject("3.png", new ByteArrayInputStream(bytes3), bytes3.length, ZonedDateTime.now()));
        minioUtils.uploadsObject(objects);
    }
}

 pom 文件引入依赖

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.4.2</version>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.8.1</version>
</dependency>

 

 注意事项:MinIo sdk是最新,和旧版一些方法有差异,请求是异步的


 

 开启永久访问策略

  1.  控制台界面找到你要永久开放的桶
  2. 点击“manage”
  3. 在点击访问规则
  4. 设置访问规则“prefix” * 权限只读就可以了
  5. 资源访问路径 http://xxx.xxx.xxx:9000/桶/文件名

 

 

 

 

 

 

posted @ 2022-07-10 11:22  天葬  阅读(9999)  评论(0编辑  收藏  举报