分布式文件存储系统minio了解下

什么是minio

minio 是一个基于 Apache License v2.0 开源协议的对象存储服务。非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小。 是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。

如果不考虑文件存储上云,minio 是一个非常不错的选择,并且支持分布式部署。

如何使用 minio 进行文件上传

xml 复制代码
// 引入mioio的依赖包
 <!-- minio -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>7.1.4</version>
        </dependency>
java 复制代码
// controller层
@PostMapping(value = "/uploadFile", headers = "content-type=multipart/form-data")
public Response<List<FileReturn>> uploadFiles(List<MultipartFile> fileList) {
        return fileService.uploadFileList(fileList);
    }
java 复制代码
// service层 --- 伪代码
public List<FileReturn> uploadFileList(List<MultipartFile> fileList) {
        // 参数校验
        if (CollectionUtils.isEmpty(fileList)) {
            // throw new Exception
        }

        List<FileVO> fileVOList = new ArrayList<>();
        List<FileReturn> fileReturnList = new ArrayList<>();
        // String userId = xxxx;
        for (MultipartFile file : fileList) {
            // 校验文件 todo

            // 开始上传
            try {
                // 将文件存入minio
                Map<String, String> fileMap = minioClient.putObject(file);
                // 创建文件对象,设置属性
                FileVO fileVO = new FileVO()
                        .init(userId)
                        .setFileType(suffix)
                        .setFileOldName(Base64.decodeStr(fileMap.get(FileModel.OLD_NAME), "UTF-8"))
                        .setFileName(fileMap.get(FileModel.NAME))
                        .setFilePath(fileMap.get(FileModel.NAME))
                        .setFileNetPath(fileMap.get(FileModel.URL))
                        .setFileSize(new BigDecimal(fileMap.get(FileModel.SIZE)))
                        .setFileUploadUser(userId)
                        .setFileUploadTime(LocalDateTime.now());
                fileVO.setId(IdWorker.getId());
                fileVOList.add(fileVO);

                // 返回文件id,文件url,文件名
                FileReturn fileReturn = new FileReturn().setFileId(fileVO.getId()).setFileNetPath(fileVO.getFileNetPath()).setFileAbsolutePath(this.preview(fileVO.getFileNetPath())).setFileOldName(fileVO.getFileOldName());
                fileReturnList.add(fileReturn);

            } catch (Exception e) {
                // 删除minio中已经保存的文件
                if (fileReturnList.size() > 0) {
                    fileReturnList.forEach(vo -> minioClient.removeObject(vo.getFileNetPath()));
                }
                log.info("上传文件异常", e);
                // throw new Exception
            }
        }
        // 保存附件信息到数据库 持久化
        mapper.saveList(fileVOList);
        return fileReturnList;
    }

文件下载

java 复制代码
// service层
// 文件下载前端传入文件id --- 伪代码
 public void downloadFile(String fileId, HttpServletResponse response) {
        FileVO contractFile = mapper.selectById(fileId);
        if (!Objects.isNull(contractFile)) {
            try {
                response.setHeader("Content-Disposition", "attachment;filename=" + contractFile.getFileName());
                minioClient.getObject(contractFile.getFilePath(), response.getOutputStream());
                // 持久化:记录下载次数,根据业务来处理
                // ...
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

文件删除

java 复制代码
// service层 --- 伪代码
public String removeFile(String fileId, HttpServletResponse response) {
        FileVO contractFile = mapper.selectById(fileId);
        if (!Objects.isNull(contractFile)) {
            try {
                response.setHeader("Content-Disposition", "attachment;filename=" + contractFile.getFileName());
                // 删除minio文件
                minioClient.removeFile(contractFile.getFilePath());
                // 删除数据库文件 持久化操作
                // ...
            } catch (IOException e) {
                // return "删除失败";
            }
        }
        return "删除成功";
    }

文件预览

java 复制代码
// service层 --- 伪代码
// 返回文件的url全路径即可
 public String preview(String filePath) {
        String url = "";
        if (StringUtils.isNotEmpty(filePath)) {
            int index = filePath.indexOf('/');
            String objectName = filePath.substring(index + 1);
            url = minioClient.getObjectUrl(objectName, 24 * 3600, Method.GET);
        }
        return url;
    }

 public String getObjectUrl(String objectName, Integer expires, Method method) {
        try {
            if (expires >= 1 && expires <= 604800) {
                if (method == null) {
                    method = Method.GET;
                }
                return minioClient.getPresignedObjectUrl((GetPresignedObjectUrlArgs)((io.minio.GetPresignedObjectUrlArgs.Builder)((io.minio.GetPresignedObjectUrlArgs.Builder)GetPresignedObjectUrlArgs.builder().method(method).bucket(minioConfig.getBucket())).object(objectName)).expiry(expires, TimeUnit.SECONDS).build());
            } else {
                throw new InvalidExpiresRangeException(expires, "expires must be in range of 1 to 604800");
            }
        } catch (Throwable var6) {
            throw new BusinessException(FILE_LOAD_EXCEPTION.getCode(), FILE_LOAD_EXCEPTION.getMessage(), var6.getMessage());
        }
    }
相关推荐
TDengine (老段)6 分钟前
TDengine 时间函数 TODAY() 用户手册
大数据·数据库·物联网·oracle·时序数据库·tdengine·涛思数据
四谎真好看9 分钟前
Java 学习笔记(进阶篇2)
java·笔记·学习
码界奇点15 分钟前
KingbaseES一体化架构与多层防护体系如何保障企业级数据库的持续稳定与弹性扩展
数据库·架构·可用性测试
上官浩仁23 分钟前
springboot ioc 控制反转入门与实战
java·spring boot·spring
掘金-我是哪吒32 分钟前
分布式微服务系统架构第169集:1万~10万QPS的查当前订单列表
分布式·微服务·云原生·架构·系统架构
悟乙己38 分钟前
数据科学家如何更好地展示自己的能力
大数据·数据库·数据科学家
Zhao_yani43 分钟前
RabbitMQ相关知识
分布式·rabbitmq
叫我阿柒啊1 小时前
从Java全栈到前端框架:一位程序员的实战之路
java·spring boot·微服务·消息队列·vue3·前端开发·后端开发
皆过客,揽星河1 小时前
mysql进阶语法(视图)
数据库·sql·mysql·mysql基础语法·mysql进阶语法·视图创建修改删除
mqiqe1 小时前
架构-亿级流量性能调优实践
java·架构