尊龙的玩法的规则

新闻动态

springboot使用minio(8.5.11)-CSDN博客

发布日期:2025-03-07 17:03    点击次数:149

版权

1.配置minio MinioAutoConfiguration 类

@AllArgsConstructor@EnableConfigurationProperties({MinioProperties.class})public class MinioAutoConfiguration {    private final MinioProperties properties;    @Bean    @ConditionalOnMissingBean(MinioTemplate.class)    @ConditionalOnProperty(name = "amc.minio.url")    MinioTemplate minioTemplate() {        return new MinioTemplate(                properties.getUrl(),                properties.getAccessKey(),                properties.getSecretKey()        );    }}

2.属性类

@Data@ConfigurationProperties(prefix = "amc.minio")public class MinioProperties {    /**     * minio 服务地址 http://ip:port     */    private String url;    /**     * 用户名     */    private String accessKey;    /**     * 密码     */    private String secretKey;}

3.创建minioTemplate工具类

package com.amc.minio.entity;import cn.hutool.core.util.StrUtil;import cn.hutool.core.util.URLUtil;import io.minio.*;import io.minio.errors.*;import io.minio.http.Method;import io.minio.messages.Bucket;import io.minio.messages.Item;import lombok.RequiredArgsConstructor;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.InitializingBean;import org.springframework.util.Assert;import java.io.IOException;import java.io.InputStream;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Optional;/** * minio 交互类 * @author Administrator */@RequiredArgsConstructor@Slf4jpublic class MinioTemplate implements InitializingBean {    private final String endpoint;    private final String accessKey;    private final String secretKey;    private MinioClient client;    /**     * 创建bucket     *     * @param bucketName bucket名称     */    @SneakyThrows    public void createBucket(String bucketName) {        if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {            client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());        }    }    /**     * 合并分片文件成对象文件     *     * @param chunkBucKetName   分片文件所在存储桶名称     * @param composeBucketName 合并后的对象文件存储的存储桶名称     * @param chunkNames        分片文件名称集合     * @param objectName        合并后的对象文件名称     * @return true/false     */    @SneakyThrows    public boolean composeObject(String chunkBucKetName, String composeBucketName, List<String> chunkNames, String objectName) {        if (null == chunkBucKetName) {            chunkBucKetName = "chunk";        }        List<ComposeSource> sourceObjectList = new ArrayList<>(chunkNames.size());        for (String chunk : chunkNames) {            sourceObjectList.add(                    ComposeSource.builder()                            .bucket(chunkBucKetName)                            .object(chunk)                            .build()            );        }        client.composeObject(                ComposeObjectArgs.builder()                        .bucket(composeBucketName)                        .object(objectName)                        .sources(sourceObjectList)                        .build()        );        return true;    }    /**     * 根据md5获取所有分片文件名称(minio的文件名称 = 文件path)     * @param bucketName 桶(文件夹)名称     * @param prefix 前缀     * @return List<String>     */    @SneakyThrows    public List<String> listObjectNames(String bucketName, String prefix) {        List<String> chunkPaths = new ArrayList<>();        ListObjectsArgs listObjectsArgs;        if (StrUtil.isBlank(prefix)) {            listObjectsArgs = ListObjectsArgs.builder()                    .bucket(bucketName)                    .recursive(true)                    .build();        } else {            listObjectsArgs = ListObjectsArgs.builder()                    .bucket(bucketName)                    .prefix(prefix)                    .recursive(true)                    .build();        }        Iterable<Result<Item>> chunks = client.listObjects(listObjectsArgs);        Iterator<Result<Item>> iterator = chunks.iterator();        while(iterator.hasNext()) {            Result<Item> item = iterator.next();            chunkPaths.add(URLUtil.decode(item.get().objectName()));        }        return chunkPaths;    }    /**     * 通过文件名字判断文件是否存在如果存在返回false否则返回true     * @param bucketName 桶名称     * @param fileName 文件名称     * @return true|false     */    @SneakyThrows    public Boolean fileExists(String bucketName, String fileName) {        boolean exist = true;        try {            if(client.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build()) == null){                exist = false;            }        } catch (Exception e) {            exist = false;        }        return exist;    }    /**     * 获取全部bucket     * <p>     * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets     */    @SneakyThrows    public List<Bucket> getAllBuckets() {        return client.listBuckets();    }    /**     * @param bucketName bucket名称     */    @SneakyThrows    public Optional<Bucket> getBucket(String bucketName) {        return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();    }    /**     * @param bucketName bucket名称     */    @SneakyThrows    public Boolean bucketExists(String bucketName) {        return client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());    }    /**     * @param bucketName bucket名称     */    @SneakyThrows    public void removeBucket(String bucketName) {        client.removeBucket(RemoveBucketArgs.builder()                .bucket(bucketName)                .build());    }    /**     * 根据文件前置查询文件     *     * @param bucketName bucket名称     * @param prefix     前缀     * @param recursive  是否递归查询     * @return MinioItem 列表     */    @SneakyThrows    public List<MinioItem> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {        List<MinioItem> objectList = new ArrayList<>();        Iterable<Result<Item>> objectsIterator = client.listObjects(ListObjectsArgs.builder()                .bucket(bucketName)                .prefix(prefix)                .recursive(recursive)                .build());        for (Result<Item> itemResult : objectsIterator) {            if(itemResult.get() != null) {                objectList.add(new MinioItem(itemResult.get()));            }        }        return objectList;    }    /**     * 获取文件外链     *     * @param bucketName bucket名称     * @param objectName 文件名称     * @param expires    过期时间 <=7     * @return url     */    @SneakyThrows    public String getObjectUrl(String bucketName, String objectName, Integer expires) {        return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()                .method(Method.GET)                .bucket(bucketName)                .object(objectName)                .expiry(expires).build());    }    /**     * 创建上传文件对象的外链     *     * @param bucketName 存储桶名称     * @param objectName 欲上传文件对象的名称     * @param expiry     过期时间(分钟) 最大为7天 超过7天则默认最大值     * @return uploadUrl     */    @SneakyThrows    public String createUploadUrl(String bucketName, String objectName, Integer expiry) {        return client.getPresignedObjectUrl(                GetPresignedObjectUrlArgs.builder()                        .method(Method.PUT)                        .bucket(bucketName)                        .object(objectName)                        .expiry(expiry)                        .build()        );    }    /**     * 获取文件     *     * @param bucketName bucket名称     * @param objectName 文件名称     * @return 二进制流     */    @SneakyThrows    public InputStream getObject(String bucketName, String objectName) {        return client.getObject(GetObjectArgs.builder()                .bucket(bucketName)                .object(objectName).build());    }    /**     * 从指定桶中获取对象的前缀输入流     *     * @param bucketName 桶名     * @param objectName 对象名     * @return 读取对象前1024字节的输入流,如果发生异常则返回null     */    public InputStream getPerfixInputStream(String bucketName, String objectName){        // 读取文件的前1024字节        // 你可以根据需要调整这个值        long size = 1024;        try {            return   client.getObject(GetObjectArgs.builder()                      .bucket(bucketName)                      // 文件的起始位置                      .offset(0L)                      // 需要读取的字节数                      .length(size)                      .object(objectName).build());        } catch (Exception e) {            log.error(e.getMessage(),e);        }        return null;    }    /**     * 下载到指定位置     *     * @param bucketName bucket名称     * @param objectName 对象名称     * @param objectName 文件名称     * @return 二进制流     */    @SneakyThrows    public void downloadObject(String bucketName, String objectName, String fileName) {        client.downloadObject(DownloadObjectArgs.builder()                .bucket(bucketName)                .object(objectName)                 //必须指定文件名                .filename(fileName)                .build());    }    /**     * 复制文件     *     * @param srcBucketName Source bucket name     * @param srcObjectName Source object name     * @param bucketName    目标 bucket名称     * @param objectName    目标 文件名称     * @return 二进制流     */    @SneakyThrows    public void copyObject(String srcBucketName, String srcObjectName, String bucketName, String objectName) {        client.copyObject(CopyObjectArgs.builder()                .source(CopySource.builder()                        .bucket(srcBucketName)                        .object(srcObjectName)                        .build())                .bucket(bucketName)                .object(objectName)                .build());    }    /**     * 上传文件     *     * @param bucketName bucket名称     * @param objectName 文件名称     * @param stream     文件流     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject     */    public void putObject(String bucketName, String objectName, InputStream stream) throws Exception {        putObject(bucketName, objectName, stream, (long) stream.available(), "application/octet-stream");    }    /**     * 上传文件     *     * @param bucketName  bucket名称     * @param objectName  文件名称     * @param stream      文件流     * @param size        大小     * @param contextType 类型     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject     */    public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {        client.putObject(                PutObjectArgs.builder()                        .bucket(bucketName)                        .object(objectName).stream(stream, size, -1)                        .contentType(contextType)                        .build());    }    /**     * 获取文件信息     *     * @param bucketName bucket名称     * @param objectName 文件名称     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject     */    /*public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception {        return client.statObject(                StatObjectArgs.builder().bucket(bucketName).object(objectName).build());    }*/    /**     * 删除文件     *     * @param bucketName bucket名称     * @param objectName 文件名称     */    @SneakyThrows    public void removeObject(String bucketName, String objectName) {        client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());    }    /**     * 删除文件     *     * @param bucketName bucket名称     * @param fileNames  文件名称列表     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject     */    @SneakyThrows    public void removeObjects(String bucketName, List<String> fileNames) {        fileNames.forEach(objectName -> {            try {                client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());            } catch (Exception e) {                log.error(e.getMessage(),e);            }        });    }    /**     * 删除文件     *     * @param bucketName bucket名称     * @param fileNamePre  标识符     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject     */    @SneakyThrows    public void removeObjects(String bucketName, String fileNamePre) {        final List<String> listObjectNames = this.listObjectNames(bucketName, fileNamePre);        this.removeObjects(bucketName,listObjectNames);    }    @Override    public void afterPropertiesSet() throws Exception {        Assert.hasText(endpoint, "Minio url 为空");        Assert.hasText(accessKey, "Minio accessKey为空");        Assert.hasText(secretKey, "Minio secretKey为空");        this.client = MinioClient.builder()                .endpoint(endpoint)                .credentials(accessKey, secretKey)                .build();    }}

4.初始化桶类

@Slf4jpublic class MinioBucketInit implements Runnable{    /**     算法文件存放的minio桶     */    public  String[] buckets;    private MinioTemplate minioTemplate;    public MinioBucketInit(MinioTemplate minioTemplate,String[] buckets) {        this.minioTemplate = minioTemplate;        this.buckets = buckets;    }    @Override    public void run() {        if(buckets==null) {            return;        }        for (int i = 0; i <buckets.length ; i++) {            //判断桶是否存在            Boolean bucketNameExit = minioTemplate.bucketExists(buckets[i]);            if(!bucketNameExit){                minioTemplate.createBucket(buckets[i]);            }        }    }}

5.使用

log.debug("初始化minio的桶");            //判断有没有桶threadPoolTaskExecutor.execute(new MinioBucketInit(minioTemplate,new String[]{bucketName}));
  //获取源文件InputStream inputStream = minioTemplate.getObject(attachment.getBucketName(), attachment.getFilePath());  //判断文件是否存在 Boolean fileExists = minioTemplate.fileExists(attachment.getBucketName(), attachment.getFilePath());//上传文件到miniominioTemplate.putObject(MinioBucketInit.ALGORITH_MBUCKET, path, inputStream);

6.注意

1.上传时如果流是空的,不上传不成功的

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树NIONIO概述151370 人正在系统学习中 本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。