Minio+MultipartFile+IOUtils文件上传与下载

一、Minio

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
官方文档:https://docs.min.io/cn/minio-client-quickstart-guide.html

二、MultipartFile

MultipartFile是spring类型,代表HTML中form data方式上传的文件,包含二进制数据+文件名称。
官方文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/multipart/MultipartFile.html
MultipartFile与File相互转换:https://blog.csdn.net/sdut406/article/details/85647982

三、IOUtils与FileUtils

参照以前的文本输入输出,都是通过反复的创建InputStream, InputReader, OutputStream, OutputWriter等方式,较为复杂。
Apache为我们提供了一个commons-io.jar包,包含了许多IO相关的工具,使得输入输入出文本变得更为便捷。
(1)读文件

// FileUtils方式  
List<String> lines = FileUtils.readLines(file, "UTF-8");  
  
// IOUtils方式  
List<String> lines = IOUtils.readLines(new FileInputStream(file), "UTF-8");  

(2)写文件(批量且覆盖)

// FileUtils  
FileUtils.writeLines(file, "UTF-8", lines);  
  
// IOUtils  
IOUtils.writeLines(lines, null, new FileOutputStream(file));  

(3)写文件(单行写入)

try {  
    OutputStream os = new FileOutputStream(file, true);  
    IOUtils.writeLines(lines, null, os, "UTF-8");  
} catch (IOException e) {  
    e.printStackTrace();  
}  

(4)官方文档
FileUtils:https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/FileUtils.html
IOUtils:https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/IOUtils.html

四、工具类

import io.minio.MinioClient;
import cn.hutool.core.io.IoUtil;
import org.springframework.web.multipart.MultipartFile;
import lombok.RequiredArgsConstructor;
//会生成一个包含常量,和标识了NotNull的变量 的构造方法。生成的构造方法是private,如何想要对外提供使用可以使用staticName选项生成一个static方法。
@RequiredArgsConstructor  
public 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(bucketName)) {
         client.makeBucket(bucketName);
      }
   }

   /**
    * 获取全部bucket
    * <p>
    * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
    */
   @SneakyThrows
   public List<Bucket> getAllBuckets() {
      return client.listBuckets();
   }

   /**
    * 根据bucketName获取信息
    * @param bucketName bucket名称
    */
   @SneakyThrows
   public Optional<Bucket> getBucket(String bucketName) {
      return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
   }

   /**
    * 根据bucketName删除信息
    * @param bucketName bucket名称
    */
   @SneakyThrows
   public void removeBucket(String bucketName) {
      client.removeBucket(bucketName);
   }

   /**
    * 根据文件前置查询文件
    *
    * @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(bucketName, prefix, recursive);

      while (objectsIterator.iterator().hasNext()) {
         objectList.add(new MinioItem(objectsIterator.iterator().next().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.presignedGetObject(bucketName, objectName, expires);
   }

   /**
    * 获取文件
    *
    * @param bucketName bucket名称
    * @param objectName 文件名称
    * @return 二进制流
    */
   @SneakyThrows
   public InputStream getObject(String bucketName, String objectName) {
      return client.getObject(bucketName, objectName);
   }

   /**
    * 上传文件
    *
    * @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 {
      client.putObject(bucketName, objectName, stream, 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(bucketName, objectName, stream, size, contextType);
   }

   /**
    * 获取文件信息
    *
    * @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(bucketName, objectName);
   }

   /**
    * 删除文件
    *
    * @param bucketName bucket名称
    * @param objectName 文件名称
    * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
    */
   public void removeObject(String bucketName, String objectName) throws Exception {
      client.removeObject(bucketName, objectName);
   }

   @Override
   public void afterPropertiesSet() throws Exception {
      Assert.hasText(endpoint, "Minio url 为空");
      Assert.hasText(accessKey, "Minio accessKey为空");
      Assert.hasText(secretKey, "Minio secretKey为空");
      this.client = new MinioClient(endpoint, accessKey, secretKey);
   }


文件上传方法:
public String upload(@RequestParam("file") MultipartFile file) {
    String fileName  = file.getOriginalFilename();
    Map<String, String> resultMap = new HashMap<>(4);
    resultMap.put("bucketName", "bucketName");
    resultMap.put("fileName", fileName);
    try {
        minioTemplate.putObject("bucketName", fileName, file.getInputStream());

  } catch (Exception e) {
        return "上传失败";
    }
    return "上传成功";
}


文件下载方法:
public void download(String fileName, HttpServletResponse response, HttpServletRequest request) {
    String userAgent = request.getHeader("User-Agent");
    String[] nameArray = StrUtil.split(fileName, "-");
    try (InputStream inputStream = minioTemplate.getObject(nameArray[0], nameArray[1])) {
        //解决乱码
        if ( //IE 8 至 IE 10
                userAgent.toUpperCase().contains("MSIE") ||
                         //IE 11
                        userAgent.contains("Trident/7.0")) {
            fileName = java.net.URLEncoder.encode(nameArray[1], "UTF-8");
        } else{
            fileName = new String(nameArray[1].getBytes("UTF-8"),"iso-8859-1");
        }
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        response.setContentType("application/force-download");
        response.setCharacterEncoding("UTF-8");
        IoUtil.copy(inputStream, response.getOutputStream());
    } catch (Exception e) {
        log.error("文件读取异常", e);
    }
}

参考:
(1)链接一
(2)链接二

补充:
Web Uploader官网

springboot+minio+elasticsearch+webuploader实现图床,支持给图片打标签,使用elasticsearch搜索,支持图片压缩,支持分片上传,秒传,断点续传

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
你好!使用MinIO SDK可以很容易地上传MultipartFile。以下是一个示例,假设你已经创建了一个MinIO的客户端(参考官方文档): ```java import io.minio.GetObjectArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.errors.MinioException; import org.springframework.web.multipart.MultipartFile; public class MinioUploader { private final MinioClient minioClient; public MinioUploader(MinioClient minioClient) { this.minioClient = minioClient; } public void upload(MultipartFile file, String bucketName, String objectName) throws Exception { try { PutObjectArgs args = PutObjectArgs.builder() .bucket(bucketName) .object(objectName) .stream(file.getInputStream(), file.getSize(), -1) // 上传文件的流和大小 .contentType(file.getContentType()) // 设置文件类型 .build(); minioClient.putObject(args); } catch (MinioException e) { throw new Exception("Failed to upload file " + objectName + " to bucket " + bucketName, e); } } public byte[] download(String bucketName, String objectName) throws Exception { try { GetObjectArgs args = GetObjectArgs.builder() .bucket(bucketName) .object(objectName) .build(); return minioClient.getObject(args).readAllBytes(); } catch (MinioException e) { throw new Exception("Failed to download file " + objectName + " from bucket " + bucketName, e); } } } ``` 在上面的示例中,上传的文件是从`MultipartFile`对象中获取的。`stream(file.getInputStream(), file.getSize(), -1)`用于指定上传文件的流和大小。`contentType(file.getContentType())`用于设置文件类型。你可以根据自己的需要修改这些选项。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值