Minio上传文件和删除文件

本文介绍了如何在Spring Boot应用中整合Minio进行文件上传和删除操作。重点在于POM文件配置、Minio服务配置以及FileUploadUtil工具类的实现,特别提醒在删除文件时,需要注意对删除操作的结果进行迭代处理,因为删除操作返回的是一个包含对象移除状态的惰性迭代器。
摘要由CSDN通过智能技术生成

1、pom文件

           <dependency>
                <groupId>io.minio</groupId>
                <artifactId>minio</artifactId>
                <version>8.0.3</version>
            </dependency>

2、minio配置

minio:
  url: http://192.168.5.202:9000
  accessKey: admin
  secretKey: admin123
  bucketName: test

3、minio配置

package com.pojo.file.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.minio.MinioClient;

/**
 * Minio 配置信息
 *
 * @author ruoiy
 */
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig
{
    /**
     * 服务地址
     */
    private String url;

    /**
     * 用户名
     */
    private String accessKey;

    /**
     * 密码
     */
    private String secretKey;

    /**
     * 存储桶名称
     */
    private String bucketName;

    public String getUrl()
    {
        return url;
    }

    public void setUrl(String url)
    {
        this.url = url;
    }

    public String getAccessKey()
    {
        return accessKey;
    }

    public void setAccessKey(String accessKey)
    {
        this.accessKey = accessKey;
    }

    public String getSecretKey()
    {
        return secretKey;
    }

    public void setSecretKey(String secretKey)
    {
        this.secretKey = secretKey;
    }

    public String getBucketName()
    {
        return bucketName;
    }

    public void setBucketName(String bucketName)
    {
        this.bucketName = bucketName;
    }

    @Bean
    public MinioClient getMinioClient()
    {
        return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
    }
}

4、上传和删除文件实现

package com.pojo.file.service.impl;

import com.pojo.file.domain.SysFileInfo;
import com.pojo.file.service.SysFileService;
import com.pojo.file.utils.FileUploadUtils;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.DeleteObject;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.pojo.file.config.MinioConfig;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;

/**
 * Minio 文件存储
 *
 * @author ruoyi
 */
@Service
@Primary
public class MinioSysFileServiceImpl implements SysFileService {
    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient client;

    @PostConstruct
    public void init() {
        boolean isExist = false;
        try {
            isExist = client.bucketExists(BucketExistsArgs.builder().bucket(minioConfig.getBucketName()).build());
            if (!isExist) {
                // 创建一个名为asiatrip的存储桶,用于存储照片的zip文件。
                client.makeBucket(MakeBucketArgs.builder().bucket(minioConfig.getBucketName()).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 本地文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        String fileName = FileUploadUtils.extractFilename(file);
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(file.getContentType())
                .build();
        client.putObject(args);
        return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
    }

    @Override
    public void deleteFromFileSys(SysFileInfo sysFileInfo) {
        //删除文件
// http://192.168.5.202:9000/test/2021/04/27/710fd081-fb91-4d15-abcb-f7ff70afa7f6.mp4
        //从url 获取object name bucket 后面全是object name
        String baseUrl = minioConfig.getUrl() + "/" + minioConfig.getBucketName();
        String objectName = sysFileInfo.getFilePath().replace(baseUrl, "");
        RemoveObjectArgs args = RemoveObjectArgs.builder().bucket(minioConfig.getBucketName())
                .object(objectName)
                .build();
        try {
            client.removeObject(args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void batchDeleteFromFileSys(List<SysFileInfo> sysFileInfoList) {
        String baseUrl = minioConfig.getUrl() + "/" + minioConfig.getBucketName();
        List<DeleteObject> objects = new LinkedList<>();
        sysFileInfoList.forEach(j -> {
            String objectName = j.getFilePath().replace(baseUrl, "");
            objects.add(new DeleteObject(objectName));
        });
        RemoveObjectsArgs args = RemoveObjectsArgs.builder().bucket(minioConfig.getBucketName())
                .objects(objects)
                .build();
        Iterable<io.minio.Result<io.minio.messages.DeleteError>> iterable = client.removeObjects(args);
        iterable.forEach(j -> {
            
        });

    }
}

FileUploadUtil

package com.pojo.file.utils;

import java.io.File;
import java.io.IOException;

import com.pojo.common.core.utils.SecurityUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;
import com.pojo.common.core.exception.file.FileNameLengthLimitExceededException;
import com.pojo.common.core.exception.file.FileSizeLimitExceededException;
import com.pojo.common.core.exception.file.InvalidExtensionException;
import com.pojo.common.core.utils.DateUtils;
import com.pojo.common.core.utils.IdUtils;
import com.pojo.common.core.utils.StringUtils;
import com.pojo.common.core.utils.file.MimeTypeUtils;

/**
 * 文件上传工具类
 *
 * @author ruoyi
 */
public class FileUploadUtils {

    /**
     * 默认的文件名最大长度 100
     */
    public static final int DEFAULT_FILE_NAME_LENGTH = 200;

    /**
     * 资源映射路径 前缀
     */
    @Value("${file.prefix}")
    public String localFilePrefix;

    /**
     * 根据文件路径上传
     *
     * @param baseDir 相对应用的基目录
     * @param file    上传的文件
     * @return 文件名称
     * @throws IOException
     */
    public static final String upload(String baseDir, MultipartFile file) throws IOException {
        try {
            return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        } catch (Exception e) {
            throw new IOException(e.getMessage(), e);
        }
    }

    /**
     * 文件上传
     *
     * @param baseDir   相对应用的基目录
     * @param file      上传的文件
     * @return 返回上传成功的文件名
     * @throws FileSizeLimitExceededException       如果超出最大大小
     * @throws FileNameLengthLimitExceededException 文件名太长
     * @throws IOException                          比如读写文件出错时
     * @throws InvalidExtensionException            文件校验异常
     */
    public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
            throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
            InvalidExtensionException {
        int fileNamelength = file.getOriginalFilename().length();
        if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
        }

        assertAllowed(file, allowedExtension);

        String fileName = extractFilename(file);

        File desc = getAbsoluteFile(baseDir, fileName);
        file.transferTo(desc);
        String pathFileName = getPathFileName(fileName);
        return pathFileName;
    }

    /**
     * 编码文件名
     */
    public static final String extractFilename(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
        return fileName;
    }

    private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
        File desc = new File(uploadDir + File.separator + fileName);

        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                desc.getParentFile().mkdirs();
            }
        }
        return desc;
    }

    private static final String getPathFileName(String fileName) throws IOException {
        String pathFileName = "/" + fileName;
        return pathFileName;
    }

    /**
     * 文件大小校验
     *
     * @param file 上传的文件
     * @return
     * @throws FileSizeLimitExceededException 如果超出最大大小
     * @throws InvalidExtensionException
     */
    public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
            throws FileSizeLimitExceededException, InvalidExtensionException {
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) {
            if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) {
                throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
                        fileName);
            } else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) {
                throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
                        fileName);
            } else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) {
                throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
                        fileName);
            } else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION) {
                throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
                        fileName);
            } else {
                throw new InvalidExtensionException(allowedExtension, extension, fileName);
            }
        }
    }

    /**
     * 判断MIME类型是否是允许的MIME类型
     *
     * @param extension
     * @param allowedExtension
     * @return
     */
    public static final boolean isAllowedExtension(String extension, String[] allowedExtension) {
        for (String str : allowedExtension) {
            if (str.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取文件名的后缀
     *
     * @param file 表单文件
     * @return 后缀名
     */
    public static final String getExtension(MultipartFile file) {
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (StringUtils.isEmpty(extension)) {
            extension = MimeTypeUtils.getExtension(file.getContentType());
        }
        return extension;
    }
}

   public List<String> catpture(String serial, int num) {
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("accessToken", this.getVideoAccessToken());
        paramMap.put("deviceSerial", serial.toUpperCase());
        paramMap.put("channelNo", "1");
        List<String> urlList = Lists.newArrayList();
        for (int i = 0; i < num; i++) {
            String result = HttpUtil.post("https://open.ys7.com/api/lapp/device/capture", paramMap);
            if (result.contains("\"code\":\"200\"")) {
                JSONObject jsonObject = JSONUtil.parseObj(result);
                JSONObject data = jsonObject.getJSONObject("data");
                String picUrl = data.getStr("picUrl");
// 从url获取文件流
                byte[] files = HttpUtil.downloadBytes(picUrl);
                String fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + ".jpg";
               
//上传文件流
 PutObjectArgs args = PutObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(fileName)
                        .stream(new ByteArrayInputStream(files), files.length, -1)
                        .build();
                minioClient.putObject(args);
                urlList.add(minioConfig.getFileUrl() + "/" + minioConfig.getBucketName() + "/" + fileName);
            }
        }
        return urlList;
    }

注意,批量删除文件必须要对删除操作返回的结果进行迭代

问题:一开始一直按照官网示例,进行试验,发现却没有效果。原因请注意一句话:
Iterable<Result<DeleteError>> - Lazy iterator contains object removal status.

一定要对results 进行迭代。

Minio上传本地文件

 public String upload(String fileLoc) {
        String fileName = LocalDateUtil.getCurrentTimeStr(LocalDateUtil.DATE_PATTERN_yyyyMMdd1) + "/" + UUID.fastUUID().toString() + ".jpg";
        UploadObjectArgs uploadObjectArgs = null;
        try {
            uploadObjectArgs = UploadObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    //文件绝对路径
                    .filename(fileLoc)
                    //文件名
                    .object(fileName)
                    .build();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (Objects.isNull(uploadObjectArgs)) {
            return null;
        }
        try {
            minioClient.uploadObject(uploadObjectArgs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String url = minioConfig.getFileUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
        return url;
    }


 

Java中,要根据MinIO上传的文件URL删除MinIO存储桶中的对应文件,首先需要确保已经安装了MinIO SDK库,并且你有正确的访问凭证(例如Access Key和Secret Key)。以下是一个基本步骤: 1. 导入所需的库: ```java import io.minio.MinioClient; import io.minio.errors.MinioException; ``` 2. 使用`MinioClient`实例并创建连接: ```java public MinioClient getClient(String endpoint, String accessKey, String secretKey) { try { return new MinioClient(endpoint, accessKey, secretKey); } catch (MinioException e) { // 处理异常 throw new RuntimeException("Failed to create Minio client", e); } } ``` 3. 创建文件URL时,它通常包含bucket名和物体路径: ```java String objectName = "your-object-name"; // 替换为你实际的对象名称 String bucketName = "your-bucket-name"; // 替换为你实际的bucket名称 // 假设url类似:http://<endpoint>/<bucketName>/<objectName> String fileUrl = "http://" + endpoint + "/" + bucketName + "/" + objectName; ``` 4. 使用`MinioClient`删除文件: ```java public void deleteFile(MinioClient client, String fileName) { try { client.removeObject(bucketName, fileName); // 删除指定对象 System.out.println("File " + fileName + " successfully deleted."); } catch (MinioException e) { System.err.println("Error deleting file: " + e.getMessage()); } } ``` 5. 调用删除函数: ```java MinioClient minioClient = getClient("your-endpoint", "accessKey", "secretKey"); deleteFile(minioClient, objectName); ``` **注意事项:** - 确保你有足够的权限删除文件(通常是拥有该对象的写入权限)。 - 文件URL中的`endpoint`应该是MinIO服务器的URL,而不是前缀。 - 如果文件正在被其他用户下载,删除操作可能会失败。在这种情况下,你可能需要等待一段时间或者设置合适的过期策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值