MinIO的使用

本文详细介绍了如何在Windows和Linux环境下安装MinIO,包括使用可执行文件和Docker容器部署,以及如何在SpringBoot项目中集成MinIO进行文件上传、下载和管理。此外,还介绍了MinIO的基本概念和特点,以及如何配置和使用ACCESS_KEY和SECRET_KEY。
摘要由CSDN通过智能技术生成

一. window环境安装

1. 安装包下载地址:https://min.io/download#/windows,下载一个可执行文件  minio.exe
2. 在想安装目录新建一个minio文件夹,并把minio.exe文件放入minio文件夹中,并且在该文件夹新建一个data文件夹
3. 进入minio文件夹,在路径输入cmd,输入执行 minio.exe server data 命令
4. 若需要换端口则需要执行 minio.exe server data --console-address ":9100" --address ":9101" 注意代码上配置文件需要设置成9101
5. 浏览器输入域地址:http://ip:9101 账号 minioadmin 密码:minioadmin

2.linux环境安装

1. 使用docker安装minio
2. 下载镜像 docker pull minio/minio 
3. 查看镜像 docker images
4. 创建目录,一个用来存放配置,一个用来存储上传文件的目录,启动前需要先创建Minio外部挂载的配置文件( /usr/local/minio/config),和存储上传文件的目录( /usr/local/minio/data)
5. 创建容器并运行,下面运行指令

docker run \
-p 19000:9000 \
-p 9090:9090 \
--net=host \
--name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=minioadmin" \
-e "MINIO_SECRET_KEY=minioadmin" \
-v /usr/local/minio/data:/data \
-v /usr/local/minio/config:/root/.minio \
 minio/minio server \
/data --console-address ":9090" -address ":19000
命令描述
-p 19000:9000 -p 9090:9090这是端口映射,前一个是服务器的端口,后一个是客户端也就是api接口访问的端口地址
–name minio这是给新创建的容器命名的选项,名字是 “minio”
–net=host这是网络设置,表示容器将使用主机的网络栈,这样就不需要在容器内部配置网络
-d --restart=always这是运行容器的其他选项,-d使容器在后台运行,–restart=always表示容器总是会在退出后自动重启
-e “MINIO_ACCESS_KEY=minioadmin”用户名
-e “MINIO_SECRET_KEY=minioadmin”密码
-v /usr/local/minio/data:/data这意味着将宿主机上的/usr/local/minio/data 目录挂载到容器内的 /data 目录
-v /usr/local/minio/config:/root/.minio将宿主机上的 /usr/local/minio/config 目录挂载到容器内的 /root/.minio 目录
minio/minio server <br/>/data --console-address ":9090" -address ":19000这是容器内要运行的命令,启动一个名为 “minio” 的服务器,数据存储在 /data 目录下,服务器的控制台地址为 “:9090”,服务地址为 “:19000”
\换行


6.访问操作
http://ip:9090/login  账号:minioadmin 密码:minioadmin

3.MinIO的介绍使用

3.1 MinIO概述

官网地址:https://minio.org.cn
MinIO是一款基于Apache License v2.0开源协议的分布式文件系统(或者叫对象存储服务),可以做为云存储的解决方案用来保存海量的图片、视频、文档等。由于采用Golang实现,服务端可以工作在Windows、Linux、 OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令就可以运行起来。

MinIO兼容亚马逊S3(Simple Storage Service,简单存储服务)云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而且每个对象文件可以是任意大小,从几kb到最大5T不等。

3.2 MinIO特点

1. 高性能:作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率;
2. 可扩容:不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心;
3. SDK支持: 基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持;
4. 支持纠删码:MinIO使用纠删码、Checksum来防止硬件错误和静默数据污染。在最高冗余度配  置下,即使丢失1/2的磁盘也能恢复数据;

3.3 MinIO基本概念

  1. bucket(桶) :类似文件系统的目录(文件夹);
  2. Object : 类似文件系统的文件;
  3. Keys :类似文件名;
  4. MINIO_ACCESS_KEY:访问key,类似账号;
  5. MINIO_SECRET_KEY:秘钥,类似密码。

4. springboot整合MinIO

4.1 项目准备

4.1.1 配置 ACCESS KEYS 获取

4.1.2 新建桶,用来存放文件的位置

4.1.3.点击新建的桶,里面配置公众类型,避免文件地址访问不了

4.2 配置文件设置

4.2.1 导入依赖
   <!-- https://mvnrepository.com/artifact/io.minio/minio -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.2.1</version>
        </dependency>
4.2.2 配置yml文件
minio:
  #accessKey: FPi1mrIRT7LdkVrVgKyq
  #secretKey: f0CLUsOPon8qxMFUmCqicHJFkueyWJzyk4CifsEE
  #accessKey ,secretKey值的获取在配置accessKey步骤体现
  accessKey: FjFA028O825BZ47II9fT
  secretKey: 5AumALef8wccA1caMamfD3U0DxLAQTK4Z54jQd3y
  # 存放文件的桶
  bucket: test
  # 访问路径
  endpoint: http://110.42.139.83:19000
  readPath: http://110.42.139.83:19000
  servlet:
    multipart:
      max-file-size: 200MB
      max-request-size: 200MB

4.3 工具类

@Configuration
public class MinIOConfig {
 
    @Autowired
    private MinIOConfigProperties minIOConfigProperties;
 
    // 注册MinIO实例
    @Bean
    public MinioClient buildMinioClient(){
        return MinioClient
                .builder()
                .credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey())
                .endpoint(minIOConfigProperties.getEndpoint())
                .build();
    }
}
@Component
@Slf4j
public class MinioFileHelper {

    @Autowired
    MinioClient minioClient;

    @Autowired
    MinIOConfigProperties minIOConfigProperties;

    final static String separator = "/"; //文件夹分隔符

    /**
     * 上传文件
     *
     * @param prefix      文件前缀
     * @param filename    文件名
     * @param inputStream 文件流
     * @return 文件全路径
     */
    public String uploadFile(String prefix, String filename, InputStream inputStream) {
        String filePath = builderFilePath(prefix, filename);
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object(filePath)
                    .bucket(minIOConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1)
                    .build();
            minioClient.putObject(putObjectArgs);
            StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());
            urlPath.append(separator + minIOConfigProperties.getBucket());
            urlPath.append(separator);
            urlPath.append(filePath);
            return urlPath.toString();
        } catch (Exception ex) {
            throw new RuntimeException("上传文件失败");
        }
    }
    /**
     * minio上传图片
     */
    public String uploadPicture(String prefix, String filename, InputStream inputStream) {
        String filePath = builderFilePath(prefix, filename);
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object(filePath)
                    .contentType("image/jpg")
                    .bucket(minIOConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1)
                    .build();
            minioClient.putObject(putObjectArgs);
            StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());
            urlPath.append(separator + minIOConfigProperties.getBucket());
            urlPath.append(separator);
            urlPath.append(filePath);
            return urlPath.toString();
        } catch (Exception ex) {
            throw new RuntimeException("上传文件失败");
        }
    }

    /**
     * 上传html文件
     *
     * @param prefix      文件前缀
     * @param filename    文件名
     * @param inputStream 文件流
     * @return 文件全路径
     */
    public String uploadHtmlFile(String prefix, String filename, InputStream inputStream) {
        String filePath = builderFilePath(prefix, filename);
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object(filePath) //文件名
                    .contentType("text/html")//文件类型
                    .bucket(minIOConfigProperties.getBucket())//桶名称与minio创建的桶一致
                    .stream(inputStream, inputStream.available(), -1)//文件流
                    .build();
            minioClient.putObject(putObjectArgs);
            StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());
            urlPath.append(separator + minIOConfigProperties.getBucket());
            urlPath.append(separator);
            urlPath.append(filePath);
            return urlPath.toString(); //文件全路径
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException("上传文件失败");
        }
    }

    /**
     * 删除文件
     *
     * @param pathUrl 文件全路径
     */
    public void delete(String pathUrl) {
        String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");
        int index = key.indexOf(separator);
        String bucket = key.substring(0, index);
        String filePath = key.substring(index + 1);
        // 删除Objects
        RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
        try {
            minioClient.removeObject(removeObjectArgs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 下载文件
     *
     * @param pathUrl 文件全路径
     * @return 文件流
     */
    public byte[] downLoadFile(String pathUrl) {
        String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");
        int index = key.indexOf(separator);
        String bucket = key.substring(0, index);
        String filePath = key.substring(index + 1);
        InputStream inputStream = null;
        try {
            inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //字节数组输出流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while (true) {
            try {
                if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            byteArrayOutputStream.write(buff, 0, rc);
        }
        return byteArrayOutputStream.toByteArray();
    }


    /**
     * 构建文件的绝对路径
     */
    public String builderFilePath(String dirPath, String filename) {
        StringBuilder stringBuilder = new StringBuilder(50);
        if (!StringUtils.isEmpty(dirPath)) {
            stringBuilder.append(dirPath).append(separator);
        }
        //  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); 若使用的是/则访问路径yyyy/MM/dd/文件名
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String todayStr = sdf.format(new Date());
        stringBuilder.append(todayStr).append(separator);
        stringBuilder.append(filename);
        return stringBuilder.toString();
    }

4.4 调用

@RestController
@Api(tags = "Minio文件上传")
@Slf4j
public class MinioController implements InterfaceRouteUtils {

    @Autowired
    private MinioFileService minioFileService;

    @PostMapping(MINIO_PICTURE_UPLOAD)
    @ApiOperation(value = "文件上传-图片", notes = "文件上传")
    public ResponseEntity<String> uploadPicture(MultipartFile file) {
        try {
            return new ResponseEntity<>(minioFileService.uploadPicture(file));
        } catch (BaseDocumentException e) {
            return new ResponseEntity<>(e.getCode(), e.getMessage());
        }
    }

    @PostMapping(MINIO_FILE_UPLOAD)
    @ApiOperation(value = "文件上传", notes = "文件上传")
    public ResponseEntity<String> updateFile(MultipartFile file) {
        try {
            return new ResponseEntity<>(minioFileService.uploadFile(file));
        } catch (BaseDocumentException e) {
            return new ResponseEntity<>(e.getCode(), e.getMessage());
        }
    }
}
public interface MinioFileService {

    /**
     * minio 文件上传文件
     */
    String uploadFile(MultipartFile file) throws BaseDocumentException;

    /**
     * minio 文件上传图片
     */
    String uploadPicture(MultipartFile file) throws BaseDocumentException;
}
@Service
@Slf4j
public class MinioFileServiceImpl implements MinioFileService {

    @Autowired
    private MinioFileHelper minioFileHelper;


    /**
     * minio 文件上传
     */
    @Override
    public String uploadFile(MultipartFile file) throws BaseDocumentException {
        try {
            // 获取文件名称
            String fileName = file.getOriginalFilename();
            String extension = "";
            int i = fileName.lastIndexOf('.');
            if (i > 0) {
                extension = fileName.substring(i+1);
            }
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            fileName = uuid+"."+extension;
            InputStream is = file.getInputStream();
            String imgUrl = minioFileHelper.uploadFile("file", fileName, is);
            return imgUrl;
        }catch (Exception e){
            log.error("",e);
            throw new BaseDocumentException(ErrorCode.OPERATION_ERR);
        }

    }

    @Override
    public String uploadPicture(MultipartFile file) throws BaseDocumentException {
        try {
            // 获取文件名称
            String fileName = file.getOriginalFilename();
            String extension = "";
            int i = fileName.lastIndexOf('.');
            if (i > 0) {
                extension = fileName.substring(i+1);
            }
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            fileName = uuid+"."+extension;
            InputStream is = file.getInputStream();
            String imgUrl = minioFileHelper.uploadPicture("img", fileName, is);
            return imgUrl;
        }catch (Exception e){
            log.error("",e);
            throw new BaseDocumentException(ErrorCode.OPERATION_ERR);
        }
    }
}

4.5 运行结果

接口返回路径,若是文件则直接下载,如果是图片则直接访问

  • 12
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值