Java中MinIo文件系统工具类

Java中MinIo文件系统工具类

1.准备工作

  <!--minio pom-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>7.1.0</version>
        </dependency>
#minio相关配置
minio:
  endpoint: http://192.168.2.100:9000
  accessKey: lbqVhrxLGXSzx5k
  secretKey: OVrJicN8zrUFyV8ifq8JOFWIG
  bucketName: identity
  #存储文件夹
  folder: metaFolder/
  #公网访问链接
  domain: http://192.168.2.100:9000

2.工具类方法

2.1:上传的时候可以设置文件的contentType类型目的image-20221215142444627

2.2:设置全局访问策略

因为默认是桶的权限是private,那么就在公网上不能正常访问了.一种方式是通过web端中手动设置.第二种方式就是代码手动设置.
如果不需要公网访问,那么取消即可.

image-20221215142825169

image-20221215142852807

参考这篇文章:MInIO几种不同的访问策略

2.3工具类升级版-参考用这个-静态方法调用

package com.wondertek.util.minio;

import com.wondertek.util.FileUtil;
import com.wondertek.util.InputStreamConvertMultipartFileUtil;
import com.wondertek.web.exception.enums.ErrorCodeEnum;
import com.wondertek.web.exception.exception.BizException;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.*;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.Optional;

/**
 * @description: minio工具类
 * @version:1.0
 */
@Component
@Slf4j
public class MinioUtils {

    /**
     * 上传File文件
     *
     * @param file
     * @return
     */
    public static String uploadFile(File file) {
        MultipartFile multipartFile = FileUtil.fileToMultipartFile(file);
        return uploadMultipartFile(multipartFile,minioClient,endpoint,bucketName,folder,domain);
    }

    /**
     * 上传multipartFile文件
     * @param multipartFile
     * @return
     */
    public static String uploadFile(MultipartFile multipartFile) {
        return uploadMultipartFile(multipartFile,minioClient,endpoint,bucketName,folder,domain);
    }
    /**
     * 本地上传File文件
     *
     * @param file
     * @return
     */
    public static String uploadFileLocal(File file,String accessKey,String secretKey,String endpoint,String bucketName,String folder,String domain) {
        MultipartFile multipartFile = FileUtil.fileToMultipartFile(file);
        MinioClient minioClient = createMinioClient(null, accessKey, secretKey, endpoint, bucketName);
        return uploadMultipartFile(multipartFile,minioClient,endpoint,bucketName,folder,domain);
    }

    /**
     * 上传MultipartFile文件
     * @param file
     * @param minioClient
     * @param endpoint
     * @param bucketName
     * @param folder
     * @return
     */
    private static String uploadMultipartFile(MultipartFile file, MinioClient minioClient, String endpoint, String bucketName, String folder,String domain) {
        //判断bucket是否存在
        existBucket(minioClient, bucketName);
        //判断目录路径是否存在
        if (!doesFolderExist(minioClient,bucketName, folder)) {
            try {
                createFolder(minioClient,bucketName, folder);
            } catch (Exception e) {
                //throw new RuntimeException(e);
                log.error("创建目录失败!");
            }
        }
        String fileName = file.getOriginalFilename();

        String[] split = fileName.split("\\.");
        if (split.length > 1) {
            fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];
        } else {
            fileName = fileName + System.currentTimeMillis();
        }
        String objectName = folder + fileName;
        //log.debug("objectName是路径,文件最终整合的路径的值为:{}", objectName);
        InputStream in = null;
        try {
            in = file.getInputStream();
            //此方法为动态获取contentType,可以直接预览
            String contentType = getContentTypeByFileName(fileName);
            log.info("contentType的值为:{}", contentType);
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(in, in.available(), -1)
                    //如果为流,默认不预览直接下载
                    //.contentType("application/octet-stream")
                    .contentType(contentType)
                    .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException(ErrorCodeEnum.FILE_UPLOAD_FAILURE);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //String url=endpoint + "/" + bucketName + "/" + objectName;
        String url=domain + "/" + bucketName + "/" + objectName;
        log.info("上传minIo后文件url的值为:{}", url);
        return url;
    }

    /**
     * 根据文件名称下载File类型的文件
     *
     * @param fileUrl
     * @return
     */
    public MultipartFile downloadMultipartFileByUrl(String fileUrl) {

        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            MultipartFile multipartFile = InputStreamConvertMultipartFileUtil.getMultipartFile(inputStream, fileName);
            return multipartFile;
        } catch (Exception e) {
            log.error("文件下载失败:{}", e.getMessage());
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }

    /**
     * 根据文件名称下载File类型的文件
     *
     * @param fileUrl
     * @return
     */
    public File downloadFileByUrl(String fileUrl) {
        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            MultipartFile multipartFile = InputStreamConvertMultipartFileUtil.getMultipartFile(inputStream, fileName);
            File file = FileUtil.MultipartFileToFile(multipartFile);
            return file;

        } catch (Exception e) {
            log.error("文件下载失败:{}", e.getMessage());
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }

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

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

    /**
     * 获取文件外链
     *
     * @param objectName 文件名称
     * @param expires    过期时间 <=7 秒级
     * @return url
     */
    public String getPresignedObjectUrl(String objectName,
                                        Integer expires) {
        try {
            String fileUrl = minioClient.presignedGetObject(bucketName, objectName, expires);
            return fileUrl;
        } catch (Exception e) {
            log.error("获取文件外链失败:{}", e.getMessage());
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }

    /**
     * 给presigned URL设置策略
     * 允许给POST请求的presigned URL设置策略,比如接收对象上传的存储桶名称的策略,key名称前缀,过期策略。
     *
     * @param objectName 对象名
     * @return map
     */
    public Map<String, String> presignedGetObject(String objectName) {
        try {
            PostPolicy policy = new PostPolicy(bucketName, objectName,
                    ZonedDateTime.now().plusDays(7));
            policy.setContentType("image/png");
            Map<String, String> formData = minioClient.presignedPostPolicy(policy);
            log.info("curl -X POST ");
            for (Map.Entry<String, String> entry : formData.entrySet()) {
                log.info(" -F " + entry.getKey() + "=" + entry.getValue());
            }
            return formData;
        } catch (Exception e) {
            log.error("Error occurred: " + e);
        }
        return null;
    }

    /**
     * 将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");
    }

    /**
     * 根据key删除服务器上的文件
     */
    public void deleteFileByUrl(String fileUrl) {
        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(folder + fileName).build());
            log.info("删除" + bucketName + "下的文件" + folder + fileName + "成功");
        } catch (Exception e) {
            log.error("删除文件失败:{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

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

    /**
     * 判断文件夹是否存在
     *
     * @param bucketName 存储桶
     * @param objectName 文件夹名称(去掉/)
     * @return true:存在
     */
    private static boolean doesFolderExist(MinioClient minioClient, 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;
    }

    /**
     * 创建minioClient
     */
    private static MinioClient createMinioClient(MinioClient minioClient,String accessKey,String secretKey,String endpoint,String bucketName) {
        try {
            if (null == minioClient) {
                minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey)
                        .build();
                createBucket(minioClient,bucketName);
                //设置全局访问策略
                setBucketPolicy(minioClient,bucketName);
            } else {
                //设置全局访问策略
                setBucketPolicy(minioClient,bucketName);
            }
        } catch (Exception e) {
            log.error("初始化MinIO服务器异常:{}", e);
        }
        return minioClient;
    }

    private static void setBucketPolicy(MinioClient minioClient, String bucketName) throws InvalidBucketNameException {
        try {
            String config = "{\n" +
                    "     \"Statement\": [\n" +
                    "         {\n" +
                    "             \"Action\": [\n" +
                    "                 \"s3:GetBucketLocation\",\n" +
                    "                 \"s3:ListBucket\"\n" +
                    "             ],\n" +
                    "             \"Effect\": \"Allow\",\n" +
                    "             \"Principal\": \"*\",\n" +
                    "             \"Resource\": \"arn:aws:s3:::" + bucketName + "\"\n" +
                    "         },\n" +
                    "         {\n" +
                    "       \"Action\": [\n" +
                    "                \"s3:GetObject\",\n" +
                    "                \"s3:PutObject\",\n" +
                    "                \"s3:DeleteObject\"\n" +
                    "      ],\n" +
                    "             \"Effect\": \"Allow\",\n" +
                    "             \"Principal\": {\"AWS\":[\"*\"]},\n" +
                    "             \"Resource\": \"arn:aws:s3:::" + bucketName + "/" + "**" + "\"\n" +
                    "         }\n" +
                    "     ],\n" +
                    "     \"Version\": \"2012-10-17\"\n" +
                    "}";

            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(config).build());

        } catch (ErrorResponseException | InsufficientDataException
                 | InternalException | InvalidKeyException
                 | InvalidResponseException | IOException
                 | NoSuchAlgorithmException | ServerException
                 | XmlParserException e) {
            log.error("minio设置桶:{}策略失败", bucketName, e);
        }
    }

    /**
     * description: 判断bucket是否存在,不存在则创建
     *
     * @return: void
     */
    private static void existBucket(MinioClient minioClient,String bucketName) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化Bucket
     *
     * @throws Exception 异常
     */
    private static void createBucket(MinioClient minioClient,String bucketName)
            throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, RegionConflictException {
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }

    @PostConstruct
    private void handlerInit() {
        createMinioClient(minioClient,accessKey,secretKey,endpoint,bucketName);
        log.info("MinIo初始化成功");
    }

    /**
     * 、
     * 根据文件后缀名获取contentType
     */
    public static String getContentTypeByFileName(String fileName) {
        //此方法可以替代spring中根据文件后缀名获取contentType
        Optional<MediaType> mediaType = MediaTypeFactory.getMediaType(fileName);
        String contentType = mediaType.map(MediaType::toString).orElseGet(() -> MediaType.APPLICATION_OCTET_STREAM.toString());
        return contentType;
    }

    @Autowired
    public  void setMinioClient(MinioClient minioClient) {MinioUtils.minioClient = minioClient;}
    @Value("${minio.bucketName}")
    public  void setBucketName(String bucketName) {
        MinioUtils.bucketName = bucketName;
    }
    @Value("${minio.endpoint}")
    public  void setEndpoint(String endpoint) {
        MinioUtils.endpoint = endpoint;
    }
    @Value("${minio.folder}")
    public  void setFolder(String folder) {
        MinioUtils.folder = folder;
    }
    @Value("${minio.accessKey}")
    public  void setAccessKey(String accessKey) {
        MinioUtils.accessKey = accessKey;
    }
    @Value("${minio.secretKey}")
    public  void setSecretKey(String secretKey) {
        MinioUtils.secretKey = secretKey;
    }
    @Value("${minio.domain}")
    public  void setDomain(String domain) {
        MinioUtils.domain = domain;
    }
    private static MinioClient minioClient;
    private static String bucketName;

    private static String endpoint;

    private static String folder;

    private static String accessKey;

    private static String secretKey;

    private static String domain;


    public static void main(String[] args) {
        /**
         * #minio相关配置
         * minio:
         *   endpoint: http://192.168.2.100:9000
         *   accessKey: lbqVhrxLGXSzx5k
         *   secretKey: OVrJicN8zrUFyV8ifq8JOFWIG
         *   bucketName: identity
         *   #存储文件夹
         *   folder: metaFolder/
         *   #公网访问地址
         *   domain: http://192.168.2.100:9000
         */
        File file = new File("C:\\Users\\wonder\\Desktop\\ai测试图片\\风.png");
        String url = uploadFileLocal(file,
                "lbqVhrxLGXSzx5k",
                "OVrJicN8zrUFyV8ifq8JOFWIG",
                "http://192.168.2.100:9000",
                "identity",
                "metaFolder/",
                "http://192.168.2.100:9000");


    }

}



2.4工具类普通版-service需要通过@Autowired注入utils进行调用


package com.xxy.demotest.utils.minio;

import io.minio.MinioClient;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Data
@Component
@Slf4j
public class MinIoClientConfig {

    @Value("${minio.endpoint}")
    private String endpoint;
    @Value("${minio.accessKey}")
    private String accessKey;
    @Value("${minio.secretKey}")
    private String secretKey;


    /**
     * 注入minio 客户端
     * https://www.wenjiangs.com/doc/minio-java-client-api-reference#95c359a19513fffb37878fd413d54468
     * @return
     */
    @Bean
    public MinioClient minioClient() {
        MinioClient minioClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
        return minioClient;
    }
}


package com.xxy.demotest.utils.minio;

import com.xxy.demotest.result.baseresult.ErrorCodeEnum;
import com.xxy.demotest.result.exception.BizException;
import com.xxy.demotest.utils.InputStreamConvertMultipartFileUtil;
import com.xxy.demotest.utils.WorkUtil.FileUtil;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.*;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: minio工具类
 * @version:1.0
 */
@Component
@Slf4j
public class MinioUtils {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucketName}")
    private String bucketName;

    @Value("${minio.endpoint}")
    private String endpoint;

    @Value("${minio.folder}")
    private String folder;

    @Value("${minio.accessKey}")
    private String accessKey;

    @Value("${minio.secretKey}")
    private String secretKey;


    /**
     * 上传File文件
     *
     * @param file
     * @return
     */
    public String uploadFile(File file) {
        MultipartFile multipartFile = FileUtil.fileToMultipartFile(file);
        return uploadMultipartFile(multipartFile);
    }

    /**
     * description: 上传MultipartFile文件
     *
     * @param file
     * @return: java.lang.String
     */
    public String uploadMultipartFile(MultipartFile file) {
        //判断bucket是否存在
        existBucket(bucketName);
        //判断目录路径是否存在
        if (!doesFolderExist(bucketName,folder)) {
            try {
                createFolder(bucketName,folder);
            } catch (Exception e) {
                //throw new RuntimeException(e);
                log.error("创建目录失败!");
            }
        }
        String fileName = file.getOriginalFilename();
        String[] split = fileName.split("\\.");
        if (split.length > 1) {
            fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];
        } else {
            fileName = fileName + System.currentTimeMillis();
        }
        InputStream in = null;
        try {
            in = file.getInputStream();
            //此方法为动态获取contentType,可以直接预览
            String contentType = getContentTypeByMap(fileName.substring(fileName.lastIndexOf(".")));
            log.info("contentType的值为:{}", contentType);
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(in, in.available(), -1)
                    //如果为流,默认不预览直接下载
                    //.contentType("application/octet-stream")
                    .contentType(contentType)
                    .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return endpoint + "/" + bucketName + "/"+ fileName;
    }

    /**
     * 根据文件名称下载File类型的文件
     *
     * @param fileUrl
     * @return
     */
    public  MultipartFile downloadMultipartFileByUrl(String fileUrl) {

        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            MultipartFile multipartFile = InputStreamConvertMultipartFileUtil.getMultipartFile(inputStream, fileName);
            return multipartFile;
        } catch (Exception e) {
            log.error("文件下载失败:{}", e.getMessage());
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }

    /**
     * 根据文件名称下载File类型的文件
     *
     * @param fileUrl
     * @return
     */
    public  File downloadFileByUrl(String fileUrl) {
        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            MultipartFile multipartFile = InputStreamConvertMultipartFileUtil.getMultipartFile(inputStream, fileName);
            File file = FileUtil.MultipartFileToFile(multipartFile);
            return file;

        } catch (Exception e) {
            log.error("文件下载失败:{}", e.getMessage());
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }
    /**
     * 断点下载
     *
     * @param fileName 文件名称
     * @param offset 起始字节的位置
     * @param length 要读取的长度
     * @return 流
     */
    public InputStream getObject(String fileName, long offset, long length)
            throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException {
        return minioClient.getObject(
                GetObjectArgs.builder().bucket(bucketName).object(fileName).offset(offset).length(length)
                        .build());
    }

    /**
     * 获取路径下文件列表
     *
     * @param prefix 文件名称
     * @param recursive 是否递归查找,如果是false,就模拟文件夹结构查找
     * @return 二进制流
     */
    public  Iterable<Result<Item>> listObjects( String prefix,
                                                     boolean recursive) {
        return minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
    }
    /**
     * 获取文件外链
     *
     * @param objectName 文件名称
     * @param expires 过期时间 <=7 秒级
     * @return url
     */
    public  String getPresignedObjectUrl(String objectName,
                                               Integer expires){
        try {
            String fileUrl = minioClient.presignedGetObject(bucketName, objectName, expires);
            return fileUrl;
        } catch (Exception e) {
            log.error("获取文件外链失败:{}", e.getMessage());
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }

    /**
     * 给presigned URL设置策略
     * 允许给POST请求的presigned URL设置策略,比如接收对象上传的存储桶名称的策略,key名称前缀,过期策略。
     * @param objectName 对象名
     * @return map
     */
    public Map<String, String> presignedGetObject(String objectName) {
        try {
            PostPolicy policy = new PostPolicy(bucketName, objectName,
                    ZonedDateTime.now().plusDays(7));
            policy.setContentType("image/png");
            Map<String, String> formData = minioClient.presignedPostPolicy(policy);
            log.info("curl -X POST ");
            for (Map.Entry<String, String> entry : formData.entrySet()) {
                log.info(" -F " + entry.getKey() + "=" + entry.getValue());
            }
            return formData;
        } catch (Exception e) {
            log.error("Error occurred: " + e);
        }
        return null;
    }
    /**
     * 将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");
    }

    /**
     * 根据key删除服务器上的文件
     */
    public  void deleteFileByUrl(String fileUrl) {
        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(folder + fileName).build());
            log.info("删除" + bucketName + "下的文件" + folder + fileName + "成功");
        } catch (Exception e) {
            log.error("删除文件失败:{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * 创建文件夹或目录
     *
     * @param bucketName 存储桶
     * @param objectName 目录路径
     */
    public ObjectWriteResponse createFolder(String bucketName, String objectName) throws ServerException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        return minioClient.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(
                                new ByteArrayInputStream(new byte[]{}), 0, -1)
                        .build());
    }
    /**
     * 判断文件夹是否存在
     *
     * @param bucketName 存储桶
     * @param objectName 文件夹名称(去掉/)
     * @return true:存在
     */
    public  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;
    }

    /**
     * 创建minioClient
     */
    private void createMinioClient() {
        try {
            if (null == minioClient) {
                log.info("minioClient create start");
                minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey)
                        .build();
                createBucket();
                //设置全局访问策略
                setBucketPolicy();
                log.info("minioClient create end");
            }else{
                //设置全局访问策略
               setBucketPolicy();
            }
        } catch (Exception e) {
            log.error("连接MinIO服务器异常:{}", e);
        }
    }

    private void setBucketPolicy() throws InvalidBucketNameException {
        try {
            String folderName = folder.substring(0, folder.length() - 1);
//            String json="{\n" +
//                    "    \"Version\": \"2012-10-17\",\n" +
//                    "    \"Statement\": [\n" +
//                    "        {\n" +
//                    "            \"Effect\": \"Allow\",\n" +
//                    "            \"Action\": [\n" +
//                    "                \"s3:GetObject\",\n" +
//                    "                \"s3:ListAllMyBuckets\",\n" +
//                    "                \"s3:ListBucket\",\n" +
//                    "                \"s3:PutObject\",\n" +
//                    "                \"s3:DeleteObject\",\n" +
//                    "                \"s3:GetBucketLocation\"\n" +
//                    "            ],\n" +
//                    "          \"Principal\": {\"AWS\":[\"*\"]},\n" +
//                    "            \"Resource\": [\n" +
//                    "                \"arn:aws:s3:::icloud-test\",\n" +
//                    "                \"arn:aws:s3:::icloud-test/**\"\n" +
//                    "            ]\n" +
//                    "        }\n" +
//                    "    ]\n" +
//                    "}";
            String config = "{\n" +
                    "     \"Statement\": [\n" +
                    "         {\n" +
                    "             \"Action\": [\n" +
                    "                 \"s3:GetBucketLocation\",\n" +
                    "                 \"s3:ListBucket\"\n" +
                    "             ],\n" +
                    "             \"Effect\": \"Allow\",\n" +
                    "             \"Principal\": \"*\",\n" +
                    "             \"Resource\": \"arn:aws:s3:::" + bucketName + "\"\n" +
                    "         },\n" +
                    "         {\n" +
                    "       \"Action\": [\n" +
                    "                \"s3:GetObject\",\n" +
                    "                \"s3:PutObject\",\n" +
                    "                \"s3:DeleteObject\"\n" +
                    "      ],\n" +
                    "             \"Effect\": \"Allow\",\n" +
                    "             \"Principal\": {\"AWS\":[\"*\"]},\n" +
                    "             \"Resource\": \"arn:aws:s3:::" + bucketName + "/"  + "**" + "\"\n" +
                    "         }\n" +
                    "     ],\n" +
                    "     \"Version\": \"2012-10-17\"\n" +
                    "}";

            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(config).build());

        } catch (ErrorResponseException | InsufficientDataException
                 | InternalException | InvalidKeyException
                 | InvalidResponseException | IOException
                 | NoSuchAlgorithmException | ServerException
                 | XmlParserException e) {
            log.error("minio设置桶:{}策略失败", bucketName, e);
        }
    }

    /**
     * description: 判断bucket是否存在,不存在则创建
     *
     * @return: void
     */
    public void existBucket(String name) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 初始化Bucket
     *
     * @throws Exception 异常
     */
    private void createBucket()
            throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, RegionConflictException {
        if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }
    @PostConstruct
    private void handlerInit() {
        createMinioClient();
        log.info("MinIo初始化成功");
    }
    private static Map<String, String> map = new HashMap<>();

    static {
        map.put("other", "application/octet-stream");
        map.put(".tif", "image/tiff");
        map.put("0.001", "application/x-001");
        map.put("0.301", "application/x-301");
        map.put("0.323", "text/h323");
        map.put("0.906", "application/x-906");
        map.put("0.907", "drawing/907");
        map.put(".a11", "application/x-a11");
        map.put(".acp", "audio/x-mei-aac");
        map.put(".ai", "application/postscript");
        map.put(".aif", "audio/aiff");
        map.put(".aifc", "audio/aiff");
        map.put(".aiff", "audio/aiff");
        map.put(".anv", "application/x-anv");
        map.put(".asa", "text/asa");
        map.put(".asf", "video/x-ms-asf");
        map.put(".asp", "text/asp");
        map.put(".asx", "video/x-ms-asf");
        map.put(".au", "audio/basic");
        map.put(".avi", "video/avi");
        map.put(".awf", "application/vnd.adobe.workflow");
        map.put(".biz", "text/xml");
        map.put(".bmp", "application/x-bmp");
        map.put(".bot", "application/x-bot");
        map.put(".c4t", "application/x-c4t");
        map.put(".c90", "application/x-c90");
        map.put(".cal", "application/x-cals");
        map.put(".cat", "application/vnd.ms-pki.seccat");
        map.put(".cdf", "application/x-netcdf");
        map.put(".cdr", "application/x-cdr");
        map.put(".cel", "application/x-cel");
        map.put(".cer", "application/x-x509-ca-cert");
        map.put(".cg4", "application/x-g4");
        map.put(".cgm", "application/x-cgm");
        map.put(".cit", "application/x-cit");
        map.put(".class", "java/");
        map.put(".cml", "text/xml");
        map.put(".cmp", "application/x-cmp");
        map.put(".cmx", "application/x-cmx");
        map.put(".cot", "application/x-cot");
        map.put(".crl", "application/pkix-crl");
        map.put(".crt", "application/x-x509-ca-cert");
        map.put(".csi", "application/x-csi");
        map.put(".css", "text/css");
        map.put(".cut", "application/x-cut");
        map.put(".dbf", "application/x-dbf");
        map.put(".dbm", "application/x-dbm");
        map.put(".dbx", "application/x-dbx");
        map.put(".dcd", "text/xml");
        map.put(".dcx", "application/x-dcx");
        map.put(".der", "application/x-x509-ca-cert");
        map.put(".dgn", "application/x-dgn");
        map.put(".dib", "application/x-dib");
        map.put(".dll", "application/x-msdownload");
        map.put(".doc", "application/msword");
        map.put(".dot", "application/msword");
        map.put(".drw", "application/x-drw");
        map.put(".dtd", "text/xml");
        map.put(".dwf", "Model/vnd.dwf");
        //map.put(".dwf","application/x-dwf");
        map.put(".dwg", "application/x-dwg");
        map.put(".dxb", "application/x-dxb");
        map.put(".dxf", "application/x-dxf");
        map.put(".edn", "application/vnd.adobe.edn");
        map.put(".emf", "application/x-emf");
        map.put(".eml", "message/rfc822");
        map.put(".ent", "text/xml");
        map.put(".epi", "application/x-epi");
        map.put(".eps", "application/x-ps");
        //map.put(".eps","application/postscript");
        map.put(".etd", "application/x-ebx");
        map.put(".exe", "application/x-msdownload");
        map.put(".fax", "image/fax");
        map.put(".fdf", "application/vnd.fdf");
        map.put(".fif", "application/fractals");
        map.put(".fo", "text/xml");
        map.put(".frm", "application/x-frm");
        map.put(".g4", "application/x-g4");
        map.put(".gbr", "application/x-gbr");
        map.put(".", "application/x-");
        map.put(".gif", "image/gif");
        map.put(".gl2", "application/x-gl2");
        map.put(".gp4", "application/x-gp4");
        map.put(".hgl", "application/x-hgl");
        map.put(".hmr", "application/x-hmr");
        map.put(".hpg", "application/x-hpgl");
        map.put(".hpl", "application/x-hpl");
        map.put(".hqx", "application/mac-binhex40");
        map.put(".hrf", "application/x-hrf");
        map.put(".hta", "application/hta");
        map.put(".htc", "text/x-component");
        map.put(".htm", "text/html");
        map.put(".html", "text/html");
        map.put(".htt", "text/webviewhtml");
        map.put(".htx", "text/html");
        map.put(".icb", "application/x-icb");
        map.put(".ico", "image/x-icon");
        //map.put(".ico","application/x-ico");
        map.put(".iff", "application/x-iff");
        map.put(".ig4", "application/x-g4");
        map.put(".igs", "application/x-igs");
        map.put(".iii", "application/x-iphone");
        map.put(".img", "application/x-img");
        map.put(".ins", "application/x-internet-signup");
        map.put(".isp", "application/x-internet-signup");
        map.put(".IVF", "video/x-ivf");
        map.put(".java", "java/*");
        map.put(".jfif", "image/jpeg");
        map.put(".jpe", "image/jpeg");
        //map.put(".jpe","application/x-jpe");
        map.put(".jpeg", "image/jpeg");
        map.put(".jpg", "image/jpeg");
        //map.put(".jpg","application/x-jpg");
        map.put(".js", "application/x-javascript");
        map.put(".jsp", "text/html");
        map.put(".la1", "audio/x-liquid-file");
        map.put(".lar", "application/x-laplayer-reg");
        map.put(".latex", "application/x-latex");
        map.put(".lavs", "audio/x-liquid-secure");
        map.put(".lbm", "application/x-lbm");
        map.put(".lmsff", "audio/x-la-lms");
        map.put(".ls", "application/x-javascript");
        map.put(".ltr", "application/x-ltr");
        map.put(".m1v", "video/x-mpeg");
        map.put(".m2v", "video/x-mpeg");
        map.put(".m3u", "audio/mpegurl");
        map.put(".m4e", "video/mpeg4");
        map.put(".mac", "application/x-mac");
        map.put(".man", "application/x-troff-man");
        map.put(".math", "text/xml");
        map.put(".mdb", "application/msaccess");
        //map.put(".mdb","application/x-mdb");
        map.put(".mfp", "application/x-shockwave-flash");
        map.put(".mht", "message/rfc822");
        map.put(".mhtml", "message/rfc822");
        map.put(".mi", "application/x-mi");
        map.put(".mid", "audio/mid");
        map.put(".midi", "audio/mid");
        map.put(".mil", "application/x-mil");
        map.put(".mml", "text/xml");
        map.put(".mnd", "audio/x-musicnet-download");
        map.put(".mns", "audio/x-musicnet-stream");
        map.put(".mocha", "application/x-javascript");
        map.put(".movie", "video/x-sgi-movie");
        map.put(".mp1", "audio/mp1");
        map.put(".mp2", "audio/mp2");
        map.put(".mp2v", "video/mpeg");
        map.put(".mp3", "audio/mp3");
        map.put(".aac", "audio/mp3");
        map.put(".mp4", "video/mpeg4");
        map.put(".mpa", "video/x-mpg");
        map.put(".mpd", "application/vnd.ms-project");
        map.put(".mpe", "video/x-mpeg");
        map.put(".mpeg", "video/mpg");
        map.put(".mpg", "video/mpg");
        map.put(".mpga", "audio/rn-mpeg");
        map.put(".mpp", "application/vnd.ms-project");
        map.put(".mps", "video/x-mpeg");
        map.put(".mpt", "application/vnd.ms-project");
        map.put(".mpv", "video/mpg");
        map.put(".mpv2", "video/mpeg");
        map.put(".mpw", "application/vnd.ms-project");
        map.put(".mpx", "application/vnd.ms-project");
        map.put(".mtx", "text/xml");
        map.put(".mxp", "application/x-mmxp");
        map.put(".net", "image/pnetvue");
        map.put(".nrf", "application/x-nrf");
        map.put(".nws", "message/rfc822");
        map.put(".odc", "text/x-ms-odc");
        map.put(".out", "application/x-out");
        map.put(".p10", "application/pkcs10");
        map.put(".p12", "application/x-pkcs12");
        map.put(".p7b", "application/x-pkcs7-certificates");
        map.put(".p7c", "application/pkcs7-mime");
        map.put(".p7m", "application/pkcs7-mime");
        map.put(".p7r", "application/x-pkcs7-certreqresp");
        map.put(".p7s", "application/pkcs7-signature");
        map.put(".pc5", "application/x-pc5");
        map.put(".pci", "application/x-pci");
        map.put(".pcl", "application/x-pcl");
        map.put(".pcx", "application/x-pcx");
        map.put(".pdf", "application/pdf");
        //map.put(".pdf","application/pdf");
        map.put(".pdx", "application/vnd.adobe.pdx");
        map.put(".pfx", "application/x-pkcs12");
        map.put(".pgl", "application/x-pgl");
        map.put(".pic", "application/x-pic");
        map.put(".pko", "application/vnd.ms-pki.pko");
        map.put(".pl", "application/x-perl");
        map.put(".plg", "text/html");
        map.put(".pls", "audio/scpls");
        map.put(".plt", "application/x-plt");
        map.put(".png", "image/png");
        //map.put(".png","application/x-png");
        map.put(".pot", "application/vnd.ms-powerpoint");
        map.put(".ppa", "application/vnd.ms-powerpoint");
        map.put(".ppm", "application/x-ppm");
        map.put(".pps", "application/vnd.ms-powerpoint");
        map.put(".ppt", "application/vnd.ms-powerpoint");
        //map.put(".ppt","application/x-ppt");
        map.put(".pr", "application/x-pr");
        map.put(".prf", "application/pics-rules");
        map.put(".prn", "application/x-prn");
        map.put(".prt", "application/x-prt");
        map.put(".ps", "application/x-ps");
        //map.put(".ps","application/postscript");
        map.put(".ptn", "application/x-ptn");
        map.put(".pwz", "application/vnd.ms-powerpoint");
        map.put(".r3t", "text/vnd.rn-realtext3d");
        map.put(".ra", "audio/vnd.rn-realaudio");
        map.put(".ram", "audio/x-pn-realaudio");
        map.put(".ras", "application/x-ras");
        map.put(".rat", "application/rat-file");
        map.put(".rdf", "text/xml");
        map.put(".rec", "application/vnd.rn-recording");
        map.put(".red", "application/x-red");
        map.put(".rgb", "application/x-rgb");
        map.put(".rjs", "application/vnd.rn-realsystem-rjs");
        map.put(".rjt", "application/vnd.rn-realsystem-rjt");
        map.put(".rlc", "application/x-rlc");
        map.put(".rle", "application/x-rle");
        map.put(".rm", "application/vnd.rn-realmedia");
        map.put(".rmf", "application/vnd.adobe.rmf");
        map.put(".rmi", "audio/mid");
        map.put(".rmj", "application/vnd.rn-realsystem-rmj");
        map.put(".rmm", "audio/x-pn-realaudio");
        map.put(".rmp", "application/vnd.rn-rn_music_package");
        map.put(".rms", "application/vnd.rn-realmedia-secure");
        map.put(".rmvb", "application/vnd.rn-realmedia-vbr");
        map.put(".rmx", "application/vnd.rn-realsystem-rmx");
        map.put(".rnx", "application/vnd.rn-realplayer");
        map.put(".rp", "image/vnd.rn-realpix");
        map.put(".rpm", "audio/x-pn-realaudio-plugin");
        map.put(".rsml", "application/vnd.rn-rsml");
        map.put(".rt", "text/vnd.rn-realtext");
        map.put(".rtf", "application/msword");
        //map.put(".rtf","application/x-rtf");
        map.put(".rv", "video/vnd.rn-realvideo");
        map.put(".sam", "application/x-sam");
        map.put(".sat", "application/x-sat");
        map.put(".sdp", "application/sdp");
        map.put(".sdw", "application/x-sdw");
        map.put(".sit", "application/x-stuffit");
        map.put(".slb", "application/x-slb");
        map.put(".sld", "application/x-sld");
        map.put(".slk", "drawing/x-slk");
        map.put(".smi", "application/smil");
        map.put(".smil", "application/smil");
        map.put(".smk", "application/x-smk");
        map.put(".snd", "audio/basic");
        map.put(".sol", "text/plain");
        map.put(".sor", "text/plain");
        map.put(".spc", "application/x-pkcs7-certificates");
        map.put(".spl", "application/futuresplash");
        map.put(".spp", "text/xml");
        map.put(".ssm", "application/streamingmedia");
        map.put(".sst", "application/vnd.ms-pki.certstore");
        map.put(".stl", "application/vnd.ms-pki.stl");
        map.put(".stm", "text/html");
        map.put(".sty", "application/x-sty");
        map.put(".svg", "text/xml");
        map.put(".swf", "application/x-shockwave-flash");
        map.put(".tdf", "application/x-tdf");
        map.put(".tg4", "application/x-tg4");
        map.put(".tga", "application/x-tga");
        //map.put(".tif","image/tiff");
        //map.put(".tif","application/x-tif");
        map.put(".tiff", "image/tiff");
        map.put(".tld", "text/xml");
        map.put(".top", "drawing/x-top");
        map.put(".torrent", "application/x-bittorrent");
        map.put(".tsd", "text/xml");
        map.put(".txt", "text/plain");
        map.put(".uin", "application/x-icq");
        map.put(".uls", "text/iuls");
        map.put(".vcf", "text/x-vcard");
        map.put(".vda", "application/x-vda");
        map.put(".vdx", "application/vnd.visio");
        map.put(".vml", "text/xml");
        map.put(".vpg", "application/x-vpeg005");
        map.put(".vsd", "application/vnd.visio");
        //map.put(".vsd","application/x-vsd");
        map.put(".vss", "application/vnd.visio");
        map.put(".vst", "application/vnd.visio");
        //map.put(".vst","application/x-vst");
        map.put(".vsw", "application/vnd.visio");
        map.put(".vsx", "application/vnd.visio");
        map.put(".vtx", "application/vnd.visio");
        map.put(".vxml", "text/xml");
        map.put(".wav", "audio/wav");
        map.put(".wax", "audio/x-ms-wax");
        map.put(".wb1", "application/x-wb1");
        map.put(".wb2", "application/x-wb2");
        map.put(".wb3", "application/x-wb3");
        map.put(".wbmp", "image/vnd.wap.wbmp");
        map.put(".wiz", "application/msword");
        map.put(".wk3", "application/x-wk3");
        map.put(".wk4", "application/x-wk4");
        map.put(".wkq", "application/x-wkq");
        map.put(".wks", "application/x-wks");
        map.put(".wm", "video/x-ms-wm");
        map.put(".wma", "audio/x-ms-wma");
        map.put(".wmd", "application/x-ms-wmd");
        map.put(".wmf", "application/x-wmf");
        map.put(".wml", "text/vnd.wap.wml");
        map.put(".wmv", "video/x-ms-wmv");
        map.put(".wmx", "video/x-ms-wmx");
        map.put(".wmz", "application/x-ms-wmz");
        map.put(".wp6", "application/x-wp6");
        map.put(".wpd", "application/x-wpd");
        map.put(".wpg", "application/x-wpg");
        map.put(".wpl", "application/vnd.ms-wpl");
        map.put(".wq1", "application/x-wq1");
        map.put(".wr1", "application/x-wr1");
        map.put(".wri", "application/x-wri");
        map.put(".wrk", "application/x-wrk");
        map.put(".ws", "application/x-ws");
        map.put(".ws2", "application/x-ws");
        map.put(".wsc", "text/scriptlet");
        map.put(".wsdl", "text/xml");
        map.put(".wvx", "video/x-ms-wvx");
        map.put(".xdp", "application/vnd.adobe.xdp");
        map.put(".xdr", "text/xml");
        map.put(".xfd", "application/vnd.adobe.xfd");
        map.put(".xfdf", "application/vnd.adobe.xfdf");
        map.put(".xhtml", "text/html");
        map.put(".xls", "application/vnd.ms-excel");
        //map.put(".xls","application/x-xls");
        map.put(".xlw", "application/x-xlw");
        map.put(".xml", "text/xml");
        map.put(".xpl", "audio/scpls");
        map.put(".xq", "text/xml");
        map.put(".xql", "text/xml");
        map.put(".xquery", "text/xml");
        map.put(".xsd", "text/xml");
        map.put(".xsl", "text/xml");
        map.put(".xslt", "text/xml");
        map.put(".xwd", "application/x-xwd");
        map.put(".x_b", "application/x-x_b");
        map.put(".sis", "application/vnd.symbian.install");
        map.put(".sisx", "application/vnd.symbian.install");
        map.put(".x_t", "application/x-x_t");
        map.put(".ipa", "application/vnd.iphone");
        map.put(".apk", "application/vnd.android.package-archive");
        map.put(".xap", "application/x-silverlight-app");
    }

    /**
     * 、
     * 根据文件后缀名获取contentType
     */
    public static String getContentTypeByMap(String type) {
        type = type.contains(".") ? type : "." + type;
        String contentType = map.get(type);
        if (StringUtils.isEmpty(contentType)) {
            contentType = map.get("other");
        }
        return contentType;
    }
}



2.5相关工具类

package com.wondertek.util;


import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.ObjectUtil;
import com.wondertek.web.exception.enums.ErrorCodeEnum;
import com.wondertek.web.exception.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.apache.http.entity.ContentType;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author Denglixing
 * @date 2020/6/23  17:31
 */

@Slf4j
public class FileUtil {
    /**
     * 删除文件夹中所有文件和子文件夹
     *
     * @param folderPath
     */
    public static void deleteFolderAndSubfolders(String folderPath) {
        File folder = new File(folderPath);

        // 检查文件夹是否存在
        if (!folder.exists()) {
            System.out.println("文件夹不存在.");
            return;
        }

        if (folder.isDirectory()) {
            File[] files = folder.listFiles();

            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        // 递归删除子文件夹及其内容
                        deleteFolderAndSubfolders(file.getAbsolutePath());
                    } else {
                        // 删除文件
                        if (file.delete()) {
                            log.debug("已删除文件: " + file.getName());
                        }
                    }
                }
            }
        }
        // 删除文件夹本身
        if (folder.delete()) {
            log.debug("已删除文件夹: " + folderPath);
        }
    }

    /**
     * 获取当前文件夹下面的文件列表
     *
     * @param folderPath
     * @return
     */
    public static List<String> listFiles(String folderPath) {
        List<String> objects = new ArrayList<>();
        File folder = new File(folderPath);
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    objects.add(file.getAbsolutePath());
                } else if (file.isDirectory()) {
                    listFiles(file.getAbsolutePath());
                }
            }
        }
        return objects;
    }
    /**
     * 创建文件夹
     *
     * @param path
     */
    public static void createFolder(String path) {
        File folder = new File(path);
        if (!folder.exists()) {
            folder.mkdirs();
        }
    }

    /**
     * 删除本地临时文件
     *
     * @param file :删除file对象
     */
    public static void deleteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }

    /**
     * 获取视频详情信息
     *
     * @param file
     * @return
     */
    public static HashMap<String, Object> getVideoDetail(MultipartFile file) {
        try {
            HashMap<String, Object> map = new HashMap<>();
            FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file.getInputStream()); // 获取视频文件
            frameGrabber.start();
            //视频帧数
            //视频帧率
            map.put("VideoFrameRate", frameGrabber.getVideoFrameRate());
            map.put("FrameRate", frameGrabber.getFrameRate());
            // 时长
            map.put("LengthInTime", frameGrabber.getLengthInTime() / (1000 * 1000));
            // 视频码率
            map.put("VideoBitrate", frameGrabber.getVideoBitrate() / 1000);
            map.put("format", frameGrabber.getFormat());
            //图片高度
            map.put("ImageHeight", frameGrabber.getImageHeight());
            //图片宽
            map.put("ImageWidth", frameGrabber.getImageWidth());

            //音频
            map.put("SampleRate", frameGrabber.getSampleRate());
            //音频比特率
            map.put("AudioBitrate", frameGrabber.getAudioBitrate());
            //纵横比
            map.put("AspectRatio", frameGrabber.getAspectRatio());
            frameGrabber.close();
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 保存到本地
     *
     * @param filecontent
     * @param path
     */
    public static void saveFile(MultipartFile filecontent, String path) {
        OutputStream os = null;
        InputStream inputStream = null;
        String fileName = null;
        try {
            inputStream = filecontent.getInputStream();
            fileName = filecontent.getOriginalFilename();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕,关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 将文件转换成byte数组
     *
     * @param file 目标文件
     * @return
     */
    public static byte[] fileToByte(File file) {
        byte[] bytes = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            bytes = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    /**
     * 检查文件是否有效
     *
     * @param file
     * @return
     */
    public static boolean checkFileNotNull(File file) {
        if (null == file || 0 == file.length() || !file.exists()) {
            throw new BizException(ErrorCodeEnum.FILE_NULL);
        }
        return true;
    }

    /**
     * @param :multipartFile:上传的文件
     * @param size:                限制大小
     * @param unit:限制单位(B,K,M,G)
     * @return boolean:是否大于
     * @author :xiaoxiangyuan
     * @dateTime 2020-10-21 14:42:17
     * <p>
     * 判断文件大小
     */
    public static boolean checkFileSize(MultipartFile multipartFile, int size, String unit) {
        long len = multipartFile.getSize(); // 上传文件的大小, 单位为字节.
        // 准备接收换算后文件大小的容器
        double fileSize = 0;
        if ("B".equals(unit.toUpperCase())) {
            fileSize = (double) len;
        } else if ("K".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1024;
        } else if ("M".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1048576;
        } else if ("G".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1073741824;
        }
        // 如果上传文件大于限定的容量
        if (fileSize > size) {
            return false;
        }
        return true;
    }

    /**
     * @param :originalFileSize  原始文件大小
     * @param size:              限制大小
     * @param unit:限制单位(B,K,M,G)
     * @return boolean:是否大于
     * @author :xiaoxiangyuan
     * @dateTime 2020-10-21 14:42:17
     * <p>
     * 判断文件大小
     */
    public static boolean checkFileSize(long originalFileSize, int size, String unit) {
        long len = originalFileSize; // 上传文件的大小, 单位为字节.
        // 准备接收换算后文件大小的容器
        double fileSize = 0;
        if ("B".equals(unit.toUpperCase())) {
            fileSize = (double) len;
        } else if ("K".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1024;
        } else if ("M".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1048576;
        } else if ("G".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1073741824;
        }
        // 如果上传文件大于限定的容量
        if (fileSize > size) {
            return false;
        }
        return true;
    }

    /**
     * @param url 文件在线下载地址
     * @return
     * @author :xiaoxiangyuan
     * @dateTime 2020-10-21
     * <p>
     * 将在线连接转换为Base64编码方法
     */
    public static String downloadFileConvertBase64(String url) {
        try {
            //System.out.print("开始下载" + url + "资源\n");
            URL uploadUrl = new URL(url);
            HttpURLConnection httpUrl = (HttpURLConnection) uploadUrl.openConnection();
            httpUrl.connect();
            httpUrl.getInputStream();
            InputStream is = httpUrl.getInputStream();
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            // 创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            // 每次读取的字符串长度,如果为-1,代表全部读取完毕
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            //jdk7对字节数组Base64编码,包含换行符
            //
            //jdk8编码,不包含换行符
            return Base64Encoder.encode(outStream.toByteArray());
        } catch (Exception ex) {
            //System.out.print("文件下载出错:" + ex.getMessage() + "\n");
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }


    /**
     * 将在线连接转换为byte
     *
     * @param url 文件在线下载地址
     * @return
     */
    public static byte[] downloadImgByUrl(String url) {
        try {
            URL uploadUrl = new URL(url);
            HttpURLConnection httpUrl = (HttpURLConnection) uploadUrl.openConnection();
            httpUrl.connect();
            InputStream is = httpUrl.getInputStream();
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            return outStream.toByteArray();
        } catch (Exception ex) {
            throw new BizException(ErrorCodeEnum.GET_FILE_DOWNLOAD_URL_FAIL);
        }
    }


    /**
     * 根据在线url,获取文件名称
     *
     * @param urlStr
     * @return
     * @author :xiaoxiangyuan
     */
    public static String getFileName(String urlStr) {
        String fileName = null;
        try {
            URL url = new URL(urlStr);
            URLConnection uc = url.openConnection();
            fileName = uc.getHeaderField("Content-Disposition");
            fileName = new String(fileName.getBytes("ISO-8859-1"), "GBK");
            fileName = URLDecoder.decode(fileName.substring(fileName.indexOf("filename=") + 10, fileName.length() - 1), "UTF-8");
            //log.debug("文件名为:" + fileName + "  大小" + (uc.getContentLength()/1024)+"KB")
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }

    /**
     * 截取字符串
     *
     * @param str   待截取的字符串
     * @param start 截取起始位置 ( 1 表示第一位 -1表示倒数第1位)
     * @param end   截取结束位置 (如上index)
     * @return
     * @author :xiaoxiangyuan
     */
    public static String sub(String str, int start, int end) {
        String result = null;

        if (str == null || str.equals("")) {
            return "";
        }

        int len = str.length();
        start = start < 0 ? len + start : start - 1;
        end = end < 0 ? len + end + 1 : end;

        return str.substring(start, end);
    }

    /**
     * 计算base64字符串文件大小(单位:B)
     *
     * @param base64String
     * @return double 字节大小
     */
    public static double base64FileSize(String base64String) {
        //验证是否为base64
        if (!isBase64(base64String)) {
            throw new BizException(ErrorCodeEnum.BASE64_FORMAT_ERROR);
        }

        return base64String.getBytes().length;
    }


    /**
     * @param :base64:上传的base64
     * @param size:限制大小
     * @param unit:限制单位(B,K,M,G)
     * @return boolean:是否大于
     * @dateTime 2020-10-21 14:42:17
     * <p>
     * 判断文件大小
     */
    public static boolean checkBase64Size(String base64, int size, String unit) {
        // 上传文件的大小, 单位为字节.
        double len = base64FileSize(base64);
        // 准备接收换算后文件大小的容器
        double fileSize = 0;
        if ("B".equals(unit.toUpperCase())) {
            fileSize = (double) len;
        } else if ("K".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1024;
        } else if ("M".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1048576;
        } else if ("G".equals(unit.toUpperCase())) {
            fileSize = (double) len / 1073741824;
        }
        // 如果上传文件大于限定的容量
        if (fileSize > size) {
            return false;
        }
        return true;
    }

    /**
     * base64格式校验
     *
     * @param str
     * @return
     */
    public static boolean isBase64(String str) {
        // 字符串只可能包含A-Z,a-z,0-9,+,/,=字符
        // 字符串长度是4的倍数
        // 只会出现在字符串最后,可能没有或者一个等号或者两个等号
        // 接收的str是否无换行符
        String string = str.replaceAll("[\\s*\t\n\r]", "");
        String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
        return Pattern.matches(base64Pattern, string);
    }

    /**
     * base64格式校验
     *
     * @param str
     * @return
     */
    private static boolean isBase642(String str) {
        if (str == null || str.trim().length() == 0) {
            return false;
        } else {
            if (str.length() % 4 != 0) {
                return false;
            }
            char[] charA = str.toCharArray();
            for (char c : charA) {
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
                        || c == '+' || c == '/' || c == '=') {
                    continue;
                } else {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 将MultipartFile 图片文件编码为base64
     *
     * @param file
     * @param status true加:data:multipart/form-data;base64,前缀   false 不加前缀
     * @return
     */
    public static String generateBase64(MultipartFile file, Boolean status) {
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("图片不能为空!");
        }
        String fileName = file.getOriginalFilename();
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        String contentType = file.getContentType();
        byte[] imageBytes = null;
        String base64EncoderImg = "";
        try {
            imageBytes = file.getBytes();

            /**
             * 1.Java使用BASE64Encoder 需要添加图片头("data:" + contentType + ";base64,"),
             *   其中contentType是文件的内容格式。
             * 2.Java中在使用BASE64Enconder().encode()会出现字符串换行问题,这是因为RFC 822中规定,
             *   每72个字符中加一个换行符号,这样会造成在使用base64字符串时出现问题,
             *   所以我们在使用时要先用replaceAll("[\\s*\t\n\r]", "")解决换行的问题。
             */
            if (status) {
                base64EncoderImg = "data:" + contentType + ";base64," + Base64Encoder.encode(imageBytes);
            } else {
                base64EncoderImg = Base64Encoder.encode(imageBytes);
            }
            base64EncoderImg = base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return base64EncoderImg;
    }

    public static String GetImageStr(String imgFilePath) {
        // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(imgFilePath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            log.debug("目标文件不存在,文件地址为" + imgFilePath);
        }

        // 对字节数组Base64编码

        // 返回Base64编码过的字节数组字符串
        if (data != null) {
            return Base64Encoder.encode(data);
        }
        return null;
    }

    public static boolean GenerateImage(String imgStr, String imageUrl, String imageName) {
        //对字节数组字符串进行Base64解码并生成图片
        //图像数据为空
        if (imgStr == null) {
            return false;
        }

        try {
            //Base64解码
            byte[] b = Base64Decoder.decode(imgStr);

            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    //调整异常数据
                    b[i] += 256;
                }
            }
            //生成jpeg图片
            //System.currentTimeMillis()
            //新生成的图片
            File file = new File(imageUrl);
            //创建文件夹
            file.mkdirs();
            String imgFilePath = imageUrl + imageName;
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取文件名不带后缀
     *
     * @param fileName
     * @return
     */
    public static String getFileNameNotPrefix(String fileName) {
        String prefix = fileName.substring(fileName.indexOf("."));
        int num = prefix.length();//得到后缀名长度
        String fileOtherName = fileName.substring(0, fileName.length() - num);//得到文件名。去掉了后缀
        return fileOtherName;
    }


    /**
     * 获取文件名只获取后缀
     *
     * @param fileName
     * @return
     */
    public static String getFileNamePrefix(String fileName) {
        String extName = fileName.substring(fileName.lastIndexOf(".") + 1);
        return ObjectUtil.isEmpty(extName) ? "" : extName;
    }

    /**
     * 将MultipartFile转换为File
     *
     * @param multiFile
     * @return
     */
    public static File MultipartFileToFile(MultipartFile multiFile) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        fileName = "tmp-" + fileName;
        // 获取文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        // 若须要防止生成的临时文件重复,能够在文件名后添加随机码
        try {
            //File file = File.createTempFile(FileUtil.getFileNameNotPrefix(fileName), suffix);
            File file = File.createTempFile(fileName.substring(0, fileName.lastIndexOf(".")), suffix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * url转变为 MultipartFile对象
     *
     * @param url
     * @param fileName
     * @return
     * @throws Exception
     */
    public static CommonsMultipartFile createFileItem(String url, String fileName) throws Exception {
        FileItem item = null;
        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setReadTimeout(30000);
            conn.setConnectTimeout(30000);
            //设置应用程序要从网络连接读取数据
            conn.setDoInput(true);
            conn.setRequestMethod("GET");
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStream is = conn.getInputStream();

                FileItemFactory factory = new DiskFileItemFactory(16, null);
                String textFieldName = "uploadfile";
                item = factory.createItem(textFieldName, ContentType.APPLICATION_OCTET_STREAM.toString(), false, fileName);
                OutputStream os = item.getOutputStream();

                int bytesRead = 0;
                byte[] buffer = new byte[8192];
                while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
                    os.write(buffer, 0, bytesRead);
                }
                os.close();
                is.close();
            }
        } catch (IOException e) {
            throw new RuntimeException("文件下载失败", e);
        }

        return new CommonsMultipartFile(item);
    }


    /**
     * base64转图片
     *
     * @param base64Code base64码
     */
    public static void convertBase64ToImage(String base64Code, String url) {
        BufferedImage image = null;
        byte[] imageByte = null;
        try {
            imageByte = DatatypeConverter.parseBase64Binary(base64Code);
            ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
            image = ImageIO.read(new ByteArrayInputStream(imageByte));
            bis.close();
            File outputfile = new File(url);
            ImageIO.write(image, "jpg", outputfile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static File getFile(String url) {
        //对本地文件命名
        String fileName = url.substring(url.lastIndexOf("."), url.length());
        File file = null;

        URL urlfile;
        InputStream inStream = null;
        OutputStream os = null;
        try {
            file = File.createTempFile("net_url", fileName);
            //下载
            urlfile = new URL(url);
            inStream = urlfile.openStream();
            os = new FileOutputStream(file);

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
                if (null != inStream) {
                    inStream.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return file;
    }

    /**
     * MultipartFile 保存本地
     *
     * @param file
     * @param path
     * @return
     */
    public static String downloadFile(MultipartFile file, String path) {
        String fileName = file.getOriginalFilename();
        File dest = new File(new File(path).getAbsolutePath() + "/" + fileName);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest); // 保存文件
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path + "/" + fileName;
    }

    /**
     * BufferedImage 编码转换为 base64
     *
     * @param bufferedImage
     * @return
     */
    public static String BufferedImageToBase64(BufferedImage bufferedImage) {
        //io流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            //写入流中
            ImageIO.write(bufferedImage, "png", baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //转换成字节
        byte[] bytes = baos.toByteArray();

        //转换成base64串
        String png_base64 = Base64Encoder.encode(bytes).trim();
        //删除 \r\n
        return png_base64.replaceAll("\n", "").replaceAll("\r", "");
    }

    /**
     * BufferedImage 编码转换为 base64
     * 文件格式为jpg
     *
     * @param bufferedImage
     * @return
     */
    public static String BufferedImageToBase64V2(BufferedImage bufferedImage) {
        String base64 = "";
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            //写入流中
            ImageIO.write(bufferedImage, "jpg", baos);

            //转换成base64串
            base64 = Base64Encoder.encode(baos.toByteArray());
        } catch (IOException e) {
            log.error("BufferedImageToBase64V2 ERROR:{}", e.getMessage());
        }
        return base64;
    }

    /**
     * base64 编码转换为 BufferedImage
     *
     * @param base64
     * @return
     */
    public static BufferedImage base64ToBufferedImage(String base64) {

        try {
            byte[] bytes1 = Base64Decoder.decode(base64);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
            return ImageIO.read(bais);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * File转换为MultipartFile
     *
     * @param file
     * @return
     */
    public static MultipartFile fileToMultipartFile(File file) {
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }

        return new CommonsMultipartFile(item);
    }

    private static FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }


    public static void main(String[] args) {
        System.out.println(getFileNamePrefix("mpe4.322"));


        System.out.println(getFileName("https://swi-meeting-v3.obs.cn-east-3.myhuaweicloud.com/metacosmic_conference/tmp-人像1220338467994016902.png"));
    }


}

package com.wondertek.util;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 将输入流转成文件
 * @author xiaoxiangyuan
 *
 */
public class InputStreamConvertMultipartFileUtil {

	private static Logger log = LoggerFactory.getLogger(InputStreamConvertMultipartFileUtil.class);

	 /**
     * 获取封装得MultipartFile
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return MultipartFile
     */
    public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
        FileItem fileItem = createFileItem(inputStream, fileName);
        //CommonsMultipartFile是feign对multipartFile的封装,但是要FileItem类对象
        return new CommonsMultipartFile(fileItem);
    }


    /**
     * FileItem类对象创建
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return FileItem
     */
    public static FileItem createFileItem(InputStream inputStream, String fileName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "file";
        FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
        int bytesRead = 0;
        byte[] buffer = new byte[10 * 1024 * 1024];
        OutputStream os = null;
        //使用输出流输出输入流的字节
        try {
            os = item.getOutputStream();
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            inputStream.close();
        } catch (IOException e) {
            log.error("Stream copy exception", e);
            throw new IllegalArgumentException("文件上传失败");
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    log.error("Stream close exception", e);

                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("Stream close exception", e);
                }
            }
        }
        return item;
    }

    public static void main(String[] args) {
  }
}

3.如何使用

第一种工具类:

image-20231229093613984

第二种工具类:

image-20221215143233079

image-20221215143307277

  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java小白笔记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值