Minio:一个功能强大的云存储工具

在当今的数字化时代,数据存储已经成为一项至关重要的任务。随着业务的增长和数据的增加,选择一个高效、可靠且易于管理的存储解决方案变得越来越重要。Minio是一个开源的云存储工具,具有强大的功能和可扩展性,为企业提供了可靠的存储解决方案。

一、Minio的特性

Minio是一个高性能、可扩展的对象存储服务器,具有以下特性:

  1. 可扩展性:Minio可以轻松地扩展到数百个节点和数十PB的存储容量。
  2. 云原生:Minio可以轻松地与云服务提供商集成,如AWS、Azure和Google Cloud等。
  3. 高度可靠:Minio采用分布式架构,提供了高可用性和数据冗余。
  4. 灵活性:Minio支持多种存储类,包括S3兼容、文件存储和块存储。
  5. 开源:Minio是开源的,可以免费使用并根据需求进行定制。

二、Minio工具类示例代码

1、首先,您需要在项目的pom.xml文件中添加MinIO Java SDK的依赖项。

<dependency>  
    <groupId>io.miniogroupId>  
    <artifactId>minioartifactId>  
    <version>4.4.0version>  
dependency>

2、接下来,您需要创建一个MinIO客户端配置对象,并指定MinIO服务器的URL、访问密钥和秘密密钥。您可以将这些值存储在环境变量或配置文件中。

minio.properties

minio.url=http://127.0.0.1:9000 #MinIO服务所在地址
minio.accessKey=admin #访问的key
minio.secretKey=admin123 #访问的秘钥
minio.bucketName=test #存储桶名称 

3、读取配置类


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.minio.MinioClient;

@Configuration
public class MinioConfig {

	/**
	 * 服务地址
	 */
	@Value("${minio.url}")
	private String url;

	/**
	 * 用户名
	 */
	@Value("${minio.accessKey}")
	private String accessKey;

	/**
	 * 密码
	 */
	@Value("${minio.secretKey}")
	private String secretKey;


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

}

以下是一个简单的Minio工具类示例代码,用于连接Minio服务器和操作存储桶和对象:



import io.minio.*;
import io.minio.http.Method;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class MinioClientUtil {

    private static final Logger log = Logger.getLogger(MinioClientUtil.class);


    @Autowired
    private MinioClient minioClient;

    /**
     * 服务地址
     */
    @Value("${minio.url}")
    private String url;
    /**
     * 存储桶名称
     */
    @Value("${minio.bucketName}")
    private String bucketName;


    public MinioClient getMinioClient() {
        return minioClient;
    }
    // 操作存储桶

    /**
     * 创建存储桶
     *
     * @param bucketName
     */
    public void makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            System.out.println("Error occurred while creating bucket: " + e);
        }
    }

    // 删除存储桶
    public boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
            return true;
        } catch (Exception e) {
            System.out.println("Error occurred while removing bucket: " + e);
            return false;
        }
    }

    // 检查存储桶是否存在
    public boolean bucketExists(String bucketName) {
        try {
            return minioClient.bucketExists(BucketExistsArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            System.out.println("Error occurred while checking bucket existence: " + e);
            return false;
        }
    }

    // 上传对象到存储桶中
    public void putObject(String bucketName, String objectName, InputStream data, long dataSize) throws IOException {
        try {
            minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(data, dataSize, -1) // 设置输入流的数据大小和分段大小,-1表示不分段。
                    .build());
        } catch (Exception e) {
            System.out.println("Error occurred while uploading object: " + e);
        } finally {
            if (data != null) {
                data.close(); // 关闭输入流。
            }
        }
    }


    //操作文件对象

    /**
     * 上传文件
     * @param file
     * @param filePath
     * @return
     */
    public boolean uploadFile(MultipartFile file, String filePath) {
        boolean b = false;
        try {
            PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(filePath)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            minioClient.putObject(args);
            b = true;
        } catch (Exception e) {
            b = false;
            log.error("上传文件到minio失败!!" + e.getMessage());
        }
        return b;
    }


    public String uploadFileByUrl(MultipartFile file, String filePath) {
        try {
            PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(filePath)
                    .stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
            minioClient.putObject(args);
        } catch (Exception e) {
            throw new RuntimeException("上传文件到minio失败!!" + e.getMessage());
        }
        return url + "/" + bucketName + "/" + filePath;
    }

    /**
     * 附件下载
     *
     * @param attachmentName         附件原始名称
     * @param attachmentNameInServer 存储在文件服务器中的附件名称
     * @param httpServletResponse    httpServletResponse
     */

    public void download(String attachmentName, String attachmentNameInServer,
                         HttpServletResponse httpServletResponse) {
        try {
            StatObjectResponse statObjectResponse = minioClient
                    .statObject(StatObjectArgs.builder().bucket(bucketName).object(attachmentNameInServer).build());
            httpServletResponse.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(attachmentName, "UTF-8"));
            httpServletResponse.setContentType(statObjectResponse.contentType());
            // httpServletResponse.setContentType("application/octet-stream");
            httpServletResponse.setCharacterEncoding("UTF-8");
            InputStream inputStream = minioClient
                    .getObject(GetObjectArgs.builder().bucket(bucketName).object(attachmentNameInServer).build());
            IOUtils.copy(inputStream, httpServletResponse.getOutputStream());
        } catch (Exception e) {
            throw new RuntimeException("minio下载文件失败!!" + e.getMessage());
        }

    }

    /**
     * 获取预览URL 注:.txt的附件会乱码,PDF正常 注:默认有效期7天
     *
     * @param bucketName             桶名称
     * @param attachmentNameInServer 存储在文件服务器中的附件名称
     * @return
     */

    public String getPresignedUrl(String bucketName, String attachmentNameInServer) {
        try {
            minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(attachmentNameInServer).build());
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET)
                    .bucket(bucketName).object(attachmentNameInServer).build());
        } catch (Exception e) {
            throw new RuntimeException("minio生成文件临时分享链接失败!!" + e.getMessage());
        }

    }

    /**
     * 删除附件
     *
     * @param bucketName             桶名称
     * @param attachmentNameInServer 存储在文件服务器中的附件名称
     */
    public void remove(String bucketName, String attachmentNameInServer) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(attachmentNameInServer).build());
        } catch (Exception e) {
            throw new RuntimeException("minio删除文件失败!!" + e.getMessage());
        }
    }


    public InputStream getFileInputStream(String attachmentNameInServer) {
        InputStream inputStream = null;
        try {
            inputStream = minioClient
                    .getObject(GetObjectArgs.builder().bucket(bucketName).object(attachmentNameInServer).build());
        } catch (Exception e) {
            throw new RuntimeException("minio下载文件失败!!" + e.getMessage());
        }
        return inputStream;
    }

    /**
     * 多图片zip下载
     */
    public void batchDownload(List<String> filenames, String zip, HttpServletResponse res, HttpServletRequest
            req) {
        try {
            BucketExistsArgs bucketArgs = BucketExistsArgs.builder().bucket(bucketName).build();
            boolean bucketExists = minioClient.bucketExists(bucketArgs);
            BufferedOutputStream bos = null;
            res.reset();
            bos = new BufferedOutputStream(res.getOutputStream());
            ZipOutputStream out = new ZipOutputStream(bos);
            res.setHeader("Access-Control-Allow-Origin", "*");
            for (int i = 0; i < filenames.size(); i++) {
                GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
                        .object(filenames.get(i)).build();
                InputStream object = minioClient.getObject(objectArgs);
                byte buf[] = new byte[1024];
                int length = 0;
                res.setCharacterEncoding("utf-8");
                res.setContentType("application/force-download");// 设置强制下载不打开
                res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                res.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoding(zip, req) + ".zip");
                out.putNextEntry(new ZipEntry(filenames.get(i).substring(filenames.get(i).lastIndexOf("/") + 1)));
                while ((length = object.read(buf)) > 0) {
                    out.write(buf, 0, length);
                }
            }
            out.close();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String filenameEncoding(String filename, HttpServletRequest request) throws
            UnsupportedEncodingException {
        // 获得请求头中的User-Agent
        String agent = request.getHeader("User-Agent");
        // 根据不同的客户端进行不同的编码

        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

三、总结

MinIO是一个高性能、可扩展、易用的开源对象存储服务。它兼容亚马逊S3云存储服务接口,可以方便地与现有的工具和生态系统集成。MinIO以其卓越的性能、可扩展性和易用性而闻名,适用于各种场景下的数据存储需求。无论是在单机环境下还是在分布式环境下,MinIO都可以提供可靠、高效的数据存储解决方案。

你可能感兴趣的:(minio,java)