Minio Note [vaynexiao]

学习

未学
Minio_云烟成雨TD的博客-CSDN博客 https://blog.csdn.net/qq_43437874/category_10562215.html

千锋教育首发MinIO免费中文视频教程 https://www.bilibili.com/video/BV1uB4y1F7eK?from=search&seid=1307822534653799596

对象存储MInIO(免费开源对象存储服务)-阿里云OSS太贵?FastDFS配置太麻烦?MinIO帮助您解决一切问题.https://www.bilibili.com/video/BV1Ht4y1S79P

MinIo新旧版本工具类和部署文档 https://blog.csdn.net/panpeichang/article/details/116235058

MinIO客户端mc使用
https://blog.csdn.net/qq_42402854/article/details/121474018

Windows安装

下载exe后,cd到exe路径,执行

.\minio.exe server C:\minio

会出现如下内容,包括访问地址、ACCESS-KEY、SECRET-KEY

C:\Users\vaynexiao\Desktop> .\minio.exe server C:\minio
API: http://192.168.31.63:9000  http://192.168.131.1:9000  http://192.168.78.1:9000  http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin

Console: http://192.168.31.63:49343 http://192.168.131.1:49343 http://192.168.78.1:49343 http://127.0.0.1:49343
RootUser: minioadmin
RootPass: minioadmin

Command-line: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc.exe alias set myminio http://192.168.31.63:9000 minioadmin minioadmin

Documentation: https://docs.min.io

WARNING: Console endpoint is listening on a dynamic port (49343), please use --console-address ":PORT" to choose a static port.

+---------------------------------------------------------------+
| You are running an older version of MinIO released 4 days ago |
| Update: Run `mc admin update`                                 |
+---------------------------------------------------------------+

MC下载

https://dl.minio.io/client/mc/release/

pom.xml

    <dependencies>
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.3.7</version>
        </dependency>
    </dependencies>

可视化客户端

windows客户端:https://s3browser.com/download.aspx
S3 Compatible Storage
AK
SK

Java使用Minio

pom.xml

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>io.minio</groupId>
			<artifactId>minio</artifactId>
			<version>8.2.1</version>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.22</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

application.yml

server:
  port: 8080
  servlet:
    context-path: /

spring:
  application:
    name: minio-demo
  #设置请求文件大小,可自行修改
  servlet:
    multipart:
      max-file-size: 5000MB
      max-request-size: 5000MB

minio:
  endpoint: http://127.0.0.1:9000
  accessKey: minioadmin
  secretKey: minioadmin
  filHost: http://file.songshijun.top

logging:
  level:
    ROOT: info
    com.minio: debug
  pattern:
    file: '%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{50} - %msg%n'
  file:
    name: ${logging.file.path}/${spring.application.name}.log
    path: /home/logs/${spring.application.name}
    max-size: 10MB
    max-history: 30

MinioProperties.java

@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioProperties {
    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String filHost;
}

MinioConfig.java

@Configuration
public class MinioConfig {

    @Autowired
    private MinioProperties minioProperties;

    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                .endpoint(minioProperties.getEndpoint())
                .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
                .build();
    }

}

FileUploadResponse.java

@Data
@AllArgsConstructor
public class FileUploadResponse {
    private String urlHttp;
    private String urlPath;
}

MinioUtil.java

import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Slf4j
@Component
public class MinioUtil {

    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private MinioClient client;

    public void createBucket(String bucketName) throws Exception {
        if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }

    public FileUploadResponse upload(MultipartFile file, String bucketName) throws Exception {
        //判断文件是否为空
        if (null == file || 0 == file.getSize()) {
            new FileUploadResponse("", "file's size is null");
        }
        createBucket(bucketName);
        String fileName = file.getOriginalFilename();
        client.putObject(
                PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(
                        file.getInputStream(), file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build());
        String url = minioProperties.getEndpoint() + "/" + bucketName + "/" + fileName;
        String urlHost = minioProperties.getFilHost() + "/" + bucketName + "/" + fileName;
        log.info("上传文件成功url :[{}], urlHost :[{}]", url, urlHost);
        return new FileUploadResponse(url, urlHost);
    }

    public List<String> getAllBuckets() throws Exception {
        List<Bucket> buckets = client.listBuckets();
        List<String> names = new ArrayList<>();
        System.out.println(buckets.size());
        for (int i = 0; i < buckets.size(); i++) {
            names.add(buckets.get(i).name());
        }
        return names;
    }


    public Optional<Bucket> getBucketInfo(String bucketName) throws IOException, InvalidKeyException,
            NoSuchAlgorithmException, InsufficientDataException, InvalidResponseException, InternalException,
            ErrorResponseException, ServerException, XmlParserException {
        return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }

    public boolean removeBucket(String bucketName) throws Exception {
        try{
            client.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e){
            return false;
        }
        return true;
    }

    /**
     * 获取⽂件外链
     *
     * @param bucketName bucket名称
     * @param objectName ⽂件名称
     * @param expires    过期时间 <=7
     * @return url
     */
    public String getObjectURL(String bucketName, String objectName, Integer expires) throws Exception {
        return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(expires).build());
    }

    /**
     * 获取⽂件
     *
     * @param bucketName bucket名称
     * @param objectName ⽂件名称
     * @return ⼆进制流
     */
    public InputStream getObject(String bucketName, String objectName) throws Exception {
        return client.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    /**
     * 上传⽂件
     *
     * @param bucketName bucket名称
     * @param objectName ⽂件名称
     * @param stream     ⽂件流
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
     */
    public void putObject(String bucketName, String objectName, InputStream stream) throws
            Exception {
        client.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(stream, stream.available(), -1)
        .contentType(objectName.substring(objectName.lastIndexOf("."))).build());
    }

    /**
     * 上传⽂件
     *
     * @param bucketName  bucket名称
     * @param objectName  ⽂件名称
     * @param stream      ⽂件流
     * @param size        ⼤⼩
     * @param contextType 类型
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
     */
    public void putObject(String bucketName, String objectName, InputStream stream, long
            size, String contextType) throws Exception {
        client.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(stream, size, -1)
        .contentType(contextType).build());
    }

    /**
     * 获取⽂件信息
     *
     * @param bucketName bucket名称
     * @param objectName ⽂件名称
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
     */
    public StatObjectResponse getObjectInfo(String bucketName, String objectName) throws Exception {
        return client.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    public boolean removeObject(String bucketName, String objectName) throws Exception {
        try{
            client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e){
            return false;
        }
        return true;
    }

    /**
     * 查看文件对象
     * @param bucketName 存储bucket名称
     * @return 存储bucket内文件对象信息
     */
    public  List<MinIOFile> listObjects(String bucketName) {
        Iterable<Result<Item>> results = client.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).build());
        List<MinIOFile> files = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                Item item = result.get();
                MinIOFile minIOFile = new MinIOFile();
                minIOFile.setObjectName(URLDecoder.decode(item.objectName(), "utf-8"));
                minIOFile.setIsDir(item.isDir());
                minIOFile.setOwner(item.owner().displayName());
                minIOFile.setSize(item.size());
                minIOFile.setLastModified(item.lastModified().toString());
                files.add(minIOFile);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
        return files;
    }
}

MinIOFile.java

@Data
@ToString
public class MinIOFile {
    private String objectName;
    private String lastModified;
    private String owner;
    private Long size;
    private Boolean isDir;
}

MinioController.java

package com.example.demo4;

import io.minio.errors.MinioException;
import io.minio.messages.Bucket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/file")
public class MinioController {

    @Autowired
    private MinioUtil minioUtil;

    @RequestMapping("/makeBucket/{bucketName}")
    public void makeBucket(@PathVariable String bucketName) throws Exception {
        minioUtil.createBucket(bucketName);
    }

    @RequestMapping("/removeBucket/{bucketName}")
    public String removeBucket(@PathVariable String bucketName) throws Exception {
        Boolean aBoolean = minioUtil.removeBucket(bucketName);
        return aBoolean.toString();
    }

    @PostMapping("/getBucketInfo")
    public HashMap<String, String> getBucketInfo(String bucketName) throws Exception {
        Optional<Bucket> bucket = minioUtil.getBucketInfo(bucketName);
        HashMap<String, String> bucketInfo = new HashMap<String, String>();
        bucketInfo.put("name", bucket.get().name());
        bucketInfo.put("createDate", bucket.get().creationDate().toString());
        return bucketInfo;
    }

    // todo 当有文件夹时候查不出来数据???
    @PostMapping("/listObjects/{bucketName}")
    public List<MinIOFile> listObjects(@PathVariable String bucketName) throws Exception {
        return minioUtil.listObjects(bucketName);
    }

    @PostMapping("/getAllBuckets")
    public List<String> getAllBuckets() throws Exception {
        return minioUtil.getAllBuckets();
    }

    @PostMapping("/upload")
    public FileUploadResponse upload(@RequestParam(name = "file") MultipartFile file, @RequestParam String bucketName) {
        FileUploadResponse response = null;
        try {
            response = minioUtil.upload(file, bucketName);
        } catch (Exception e) {
            log.error("上传失败 : [{}]", Arrays.asList(e.getStackTrace()));
        }
        return response;
    }

    @DeleteMapping("/delete/{objectName}")
    public boolean delete(@PathVariable("objectName") String objectName, @RequestParam String bucketName) throws Exception {
        // todo 先看有没有这文件,没有报错
        boolean result = minioUtil.removeObject(bucketName, objectName);
        System.out.println("删除成功");
        return result;
    }

    @GetMapping("/download/{bucketName}/{objectName}")
    public ResponseEntity<byte[]> downloadToLocal(@PathVariable("objectName") String objectName,
                                                  @PathVariable("bucketName") String bucketName,
                                                  HttpServletResponse response) throws Exception {
        ResponseEntity<byte[]> responseEntity = null;
        InputStream stream = null;
        ByteArrayOutputStream output = null;
        try {
            // 获取"myobject"的输入流。
            stream = minioUtil.getObject(bucketName, objectName);
            //用于转换byte
            output = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = stream.read(buffer))) {
                output.write(buffer, 0, n);
            }
            byte[] bytes = output.toByteArray();

            //设置header
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Accept-Ranges", "bytes");
            httpHeaders.add("Content-Length", bytes.length + "");
//            objectName = new String(objectName.getBytes("UTF-8"), "ISO8859-1");
            //把文件名按UTF-8取出并按ISO8859-1编码,保证弹出窗口中的文件名中文不乱码,中文不要太多,最多支持17个中文,因为header有150个字节限制。
            httpHeaders.add("Content-disposition", "attachment; filename=" + objectName);
            httpHeaders.add("Content-Type", "text/plain;charset=utf-8");
//            httpHeaders.add("Content-Type", "image/jpeg");
            responseEntity = new ResponseEntity<byte[]>(bytes, httpHeaders, HttpStatus.CREATED);

        } catch (MinioException e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                stream.close();
            }
            if (output != null) {
                output.close();
            }
        }
        return responseEntity;
    }

    /**
     * 在浏览器预览图片
     */
    @GetMapping("/preViewPicture/{objectName}")
    public void preViewPicture(@PathVariable("objectName") String objectName, HttpServletResponse response) throws Exception {
        response.setContentType("image/jpeg");
        try (ServletOutputStream out = response.getOutputStream()) {
            InputStream stream = minioUtil.getObject("salt", objectName);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = stream.read(buffer))) {
                output.write(buffer, 0, n);
            }
            byte[] bytes = output.toByteArray();
            out.write(bytes);
            out.flush();
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值