Minio文件存储服务使用教程详解(附Java工具类)

本文档详细介绍了在Linux和Windows系统上安装MinIO服务器的步骤,包括端口开放、后台启动以及自定义配置。同时,提供了YAML配置示例、Spring Boot中限制文件大小的设置,并展示了Java客户端(MinioUtils工具类)的使用,包括上传、下载、管理bucket等操作。此外,还提及了部署客户端mc的配置和基本命令使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、第一部分

linux安装

启动之后有需要开放两个端口!!!

# 下载 minio
wget https://dl.min.io/server/minio/release/linux-amd64/minio
# 添加可执行权限
chmod +x minio

# 临时启动(/home/minio/data 为你存放静态文件的目录)
./minio server /home/minio/data

# 后台启动,并打印日志
nohup ./minio server /home/minio/data > /home/minio/data/minio.log &

# 自定义端口启动
./minio server --address 192.168.9.128:9111 /home/minio/data

# 后台启动 并自定义服务端口和后台管理端口
nohup ./minio server --address :9000 --console-address :9900 /feishu/minio/data > /feishu/minio/minio.log &


# 自定义文件夹地址
export MINIO_VOLUMES="/home/minio/data"
# 自定义登录minio的 access key
export MINIO_ACCESS_KEY=minioadmin
# 自定义登录minio的 secret key
export MINIO_SECRET_KEY=minioadmin

# 默认 AccessKey 和 SecretKey
AccessKey:minioadmin
SecretKey:minioadmin
# 默认端口
9000

# 访问地址
http://127.0.0.1:9000

# 开放9000端口
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --reload
windows安装
# 下载地址
https://dl.min.io/server/minio/release/windows-amd64/minio.exe

# 1.进入 minio.exe 存放目录(D:\minio\data 为你存放静态文件的目录,即存放bucket的目录,bucket下有图片)
cd D:/minio/
# 2.执行命令 (该命令在minio.exe所在目录下执行)
minio.exe server D:\minio\data
# 启动后会打印出 AccessKey 和 SecretKey 等信息
yml中配置
minio :
  endpoint : http://192.168.2.16:9000
  accesskey : minioadmin
  secretkey : minioadmin
解决限制文件大小

默认被限制为最大1MB

spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 100MB
      max-request-size: 100MB
      file-size-threshold: 100MB
相关依赖
      <!-- minio 相关依赖 -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>3.0.10</version>
        </dependency>
        <!-- alibaba的fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.51</version>
        </dependency>
        <!-- 图片压缩 -->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>
完整工具类
/**
 * @Description
 * @Author 金飞鹏  2021/9/22 11:44
 * Made in China
 */
@Slf4j
@Component
public class MinioUtils {

    private MinioClient client;

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

    //初始化
    @PostConstruct
    public void init() throws InvalidPortException, InvalidEndpointException {
        client = new MinioClient(endpoint,accessKey,secretKey);
    }


    /**
     * 创建bucket
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public void createBucket(String bucketName) {
        if (!client.bucketExists(bucketName)) {
            client.makeBucket(bucketName);
        }
    }

    /**
     * 获取全部bucket
     */
    @SneakyThrows
    public List<Bucket> getAllBuckets() {
        return client.listBuckets();
    }

    /**
     * 根据bucketName获取信息
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public Optional<Bucket> getBucket(String bucketName) {
        return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }

    /**
     * 根据bucketName删除信息
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public void removeBucket(String bucketName) {
        client.removeBucket(bucketName);
    }

    /**
     * 获取文件外链
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param expires    过期时间 <=7
     * @return url
     */
    @SneakyThrows
    public String getObjectURL(String bucketName, String objectName, Integer expires) {
        return client.presignedGetObject(bucketName, objectName, expires);
    }

    /**
     * 获取文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @return 二进制流
     */
    @SneakyThrows
    public InputStream getObject(String bucketName, String objectName) {
        return client.getObject(bucketName, objectName);
    }

    /**
     * 上传文件
     *
     * @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(bucketName, objectName, stream, stream.available(), "application/octet-stream");
    }

    /**
     * 上传文件
     *
     * @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(bucketName, objectName, stream, size, contextType);
    }

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

    /**
     * 删除文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
     */
    public void removeObject(String bucketName, String objectName) throws Exception {
        client.removeObject(bucketName, objectName);
    }

    /**
     * 上传文件
     *
     * @param file       文件
     * @param bucketName 存储桶
     * @return
     */
    public JSONObject uploadFile(MultipartFile file, String bucketName) throws Exception {
        JSONObject res = new JSONObject();
        res.put("code", 0);
        // 判断上传文件是否为空
        if (null == file || 0 == file.getSize()) {
            res.put("msg", "上传文件不能为空");
            return res;
        }
        // 判断存储桶是否存在
        createBucket(bucketName);
        // 文件名
        String originalFilename = file.getOriginalFilename();
        // 新的文件名
        String fileName = bucketName + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));
        // 开始上传
        client.putObject(bucketName, fileName, file.getInputStream(), file.getContentType());
        res.put("code", 1);
        res.put("msg", endpoint + "/" + bucketName + "/" + fileName);
        return res;
    }

    
    
    /**
     * 判断文件是否为图片
     */
    public boolean isPicture(String imgName) {
        boolean flag = false;
        if ("".equals(imgName) || null == imgName) {
            return false;
        }
        String[] arr = {"bmp", "dib", "gif", "jfif", "jpe", "jpeg", "jpg", "png", "tif", "tiff", "ico"};
        for (String item : arr) {
            if (item.equals(imgName)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    /**
     * 压缩上传文件
     *
     * @param file 文件
     * @return
     */
    public JSONObject compressionUploadFile(MultipartFile file) throws Exception {
        JSONObject res = new JSONObject();
        res.put("code", 500);
        // 判断上传文件是否为空
        if (null == file || 0 == file.getSize()) {
            res.put("msg", "上传文件不能为空");
            return res;
        }
        // 判断存储桶是否存在
        if (!client.bucketExists("jinfeipeng")) {
            client.makeBucket("jinfeipeng");
        }
        // 拿到文件后缀名,例如:png
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        // UUID 作为文件名
        String uuid = String.valueOf(UUID.randomUUID());
        // 新的文件名
        SimpleDateFormat sp =new SimpleDateFormat("yyyyMMdd");
        String date = sp.format(new Date());
        String fileName = date  + uuid + "." + suffix;
        /**
         * 判断是否是图片
         * 判断是否超过了 100K
         */
        if (isPicture(suffix) && (1024 * 1024 * 0.1) <= file.getSize()) {
            // 在项目根目录下的 upload 目录中生成临时文件
            File newFile = new File(ClassUtils.getDefaultClassLoader().getResource("static").getPath() + uuid + "." + suffix);
            // 小于 1M 的
            if ((1024 * 1024 * 0.1) <= file.getSize() && file.getSize() <= (1024 * 1024)) {
                Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.3f).toFile(newFile);
            }
            // 1 - 2M 的
            else if ((1024 * 1024) < file.getSize() && file.getSize() <= (1024 * 1024 * 2)) {
                Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.2f).toFile(newFile);
            }
            // 2M 以上的
            else if ((1024 * 1024 * 2) < file.getSize()) {
                Thumbnails.of(file.getInputStream()).scale(1f).outputQuality(0.1f).toFile(newFile);
            }
            // 获取输入流
            FileInputStream input = new FileInputStream(newFile);
            // 转为 MultipartFile
            MultipartFile multipartFile = new MockMultipartFile("file", newFile.getName(), "text/plain", input);
            // 开始上传
            client.putObject("jinfeipeng", fileName, multipartFile.getInputStream(), file.getContentType());
            // 删除临时文件
            newFile.delete();
            // 返回状态以及图片路径
            res.put("code", 200);
            res.put("msg", "上传成功");
            res.put("url", endpoint + "/" + fileName);
        }
        // 不需要压缩,直接上传
        else {
            // 开始上传
            client.putObject("jinfeipeng", fileName, file.getInputStream(), file.getContentType());
            // 返回状态以及图片路径
            res.put("code", 200);
            res.put("msg", "上传成功");
            res.put("url", endpoint + "/" + fileName);
        }
        return res;
    }

}

示例
@Controller
public class MyController {
    @Autowired
    private MinioUtils minioUtils;
    @GetMapping("/index")
    public String index(){
        return "index";
    }

    @PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam(value = "file",required = false) MultipartFile file) {
        System.out.println(file);
        JSONObject res = null;
        try {
                res = minioUtils.compressionUploadFile(file);
        } catch (Exception e) {
            e.printStackTrace();
            res.put("code", 0);
            res.put("msg", "上传失败");
        }
        return res.toJSONString();
    }
}

二、 第二部分

部署客户端mc (自此以下的文章部分,可不阅读)
wget http://dl.minio.org.cn/client/mc/release/linux-amd64/mc
chmod +x mc
./mc --help	
mv mc /usr/local/sbin/
# 剪切到/usr/local/sbin 这个目录下的原因是可以在客户端任何地方使用
配置mc

mc 将所有的配置信息都存储在 ~/.mc/config.json 文件中

# 查询mc host配置 
mc config host ls
# 添加minio服务 
mc config host add minio-server http://192.168.3.14:9000 admin 12345678 
### 解释:
#### 1.minio-server 是 你这个minio服务的别名
#### 2.http://192.168.3.14:9000 是你这个minio的访问链接,如果配置了https,这个ip需要改为域名。
#### 3.admin 12345678 是你这个minio的账号密码

# 删除host 
mc config host remove minio-server
mc命令使用
上传下载
# 查询minio服务上的所有buckets(文件和文件夹)
mc ls minio-server
# 下载文件
mc cp minio-server/tulingmall/fox/fox.jpg /tmp/
# 删除文件
mc rm minio-server/tulingmall/fox/fox.jpg
# 上传文件
mc cp zookeeper.out minio-server/tulingmall/
Bucket管理
# 创建bucket
mc mb minio-server/bucket01
# 删除bucket
mc rb minio-server/bucket02
# bucket不为空,可以强制删除 慎用
mc rb --force minio-server/bucket01
# 查询bucket03磁盘使用情况
mc du minio-server/bucket03
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值