相关文章推荐
酒量大的烈酒  ·  javascript - ...·  1 年前    · 
逃课的针织衫  ·  gpt 红队渗透_头条·  1 年前    · 
近视的金鱼  ·  cover-view ...·  1 年前    · 
帅气的单杠  ·  C++11的stoi & ...·  1 年前    · 

一、项目信息说明

minio Server版本: linux-amd64/minio 与 windows-amd64/minio.exe
minio Client版本: linux-amd64/mc 与 windows-amd64/mc.exe
minio sdk: https://dl.min.io/sdk/minio-java/

官方文档: MinIO Client (mc) — MinIO祼机使用文档

MinIO Server — MinIO祼机使用文档

二、使用说明

1.使用体验

单机部署简单,使用一条指令即可启动、配置服务器节点(服务器地址,端口、api端口)minio服务,自带页面。
mc客户端有详细中文文档,api调用接口简易

支持生命周期管理(支持日期与天数、支持设置桶内文件夹),设置后,文件会根据规则自动删除源文件

2.大体工作流程

minioServer部署—>mc客户端/api接口创建 存储桶 ---->mc客户端/api接口配置生命周期规则—>minio页面/api接口存储文件—>minio页面/api接口获取文件或文件url

三、minio Server部署

1.启动服务

linux:

./minio server /data/minio  --address ip:api调用端口  --console-address ip:服务器端口 --config-dir 配置文件地址

window:

.\minio.exe server D:\Utils\minio\  --address ip:api调用端口  --console-address ip:服务器端口 --config-dir 配置文件地址

minIO server在默认情况下会将所有配置信息存到 ${HOME}/.minio/config.json 文件中。 可用--config-dir在启动服务时重写

# 设置用户名
set MINIO_ACCESS_KEY=minioadmin
# 设置密码(8位)
set MINIO_SECRET_KEY=minioadmin
3.证书目录

TLS证书存在${HOME}/.minio/certs目录下,你需要将证书放在该目录下来启用HTTPS 。如果你是一个乐学上进的好青年,这里有一本免费的秘籍传授一你: 如何使用TLS安全的访问minio.

以下是一个带来TLS证书的MinIO server的目录结构。

Copy$ tree ~/.minio
/home/user1/.minio
├── certs
│   ├── CAs
│   ├── private.key
│   └── public.crt
└── config.json

四、MinIO Client使用

MinIO Client 简称mc,是minio服务器的客户端,对ls,cat,cp,mirror,diff,find等UNIX命令提供了一种替代方案,它支持文件系统和兼容Amazon S3的云存储服务(AWS Signature v2和v4)。

1.mc指令

ls 列出文件和文件夹。
mb 创建一个存储桶或一个文件夹。
cat 显示文件和对象内容。
pipe 将一个STDIN重定向到一个对象或者文件或者STDOUT。
share 生成用于共享的URL。
cp 拷贝文件和对象。
mirror 给存储桶和文件夹做镜像。
find 基于参数查找文件。
diff 对两个文件夹或者存储桶比较差异。
rm 删除文件和对象。
events 管理对象通知。
watch 监听文件和对象的事件。
policy 管理访问策略。
session 为cp命令管理保存的会话。
config 管理mc配置文件。
update 检查软件更新。
version 输出版本信息。

2.常用命令
//设置        别名  api地址	用户名      密码
mc alias set ALIAS HOSTNAME ACCESSKEY SECRETKEY 
//列出指定桶的当前生命周期管理规则
mc ilm list TARGET [FLAGS]
//添加新的存储桶生命周期管理规则
mc ilm add TARGET [FLAGS]
// 使用 mc ilm add 和 --expiry-days 到 在对象创建数天后使存储桶内容过期:
mc ilm add ALIAS/PATH --expiry-days "DAYS"
//使用 mc ilm remove 删除存储桶生命周期管理规则 
mc ilm remove --id "RULE" ALIAS/PATH

五、MINIO SDK(Java) Java Client API参考文档 | Minio中文文档

<!--maven-->
            <dependency>
                <groupId>io.minio</groupId>
                <artifactId>minio</artifactId>
                <version>8.4.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>com.squareup.okhttp3</groupId>
                        <artifactId>okhttp</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
<!--minio的okhttp有可能会报错-->
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>4.9.0</version>
            </dependency>
        </dependencies>
<!--gradle-->
dependencies {
    compile 'io.minio:minio:8.4.1'
#minio
minio:
  url: http://10.10.18.178:9000
  accessKey: minioadmin
  secretKey: minioadmin
  bucketName: bucket-test01
  #分区上传文件大小
  partSize: 104857600
import cn.akeparking.middleware.service.minio.MinioTemplate;
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinIoConfig {
     * 服务地址(服务接口地址)
    private String url;
     * 用户名
    private String accessKey;
    private String secretKey;
     * 存储桶名称
    private String bucketName;
    private Integer partSize;
    @Bean
    public MinioTemplate getMinioClient() {
        return new MinioTemplate(url,accessKey, secretKey,partSize);
3.常用api
1)创建储存桶

通过MinioTemplate.createBucket(bucketName)创建桶,或调用sdk包的minioClient.makeBucket方法

2)设置生命周期

通过MinioTemplate.setBucketExpirationByDays(bucketName,prefix,days,ruleName)创建对应桶的生命周期,prefix对应相应的文件夹,days对应过期天数,ruleName对应文件名称

3)存入文件

通过MinioTemplate.putObject(bucketName,objectName,base64Str/MultipartFile/InputStream)存入文件,实际上皆转为上传

PutObjectArgs putObjectArgs = PutObjectArgs.builder()
        .bucket(bucketName)
        .object(objectName)
        .stream(stream, size, partSize)
        .build();
client.putObject(putObjectArgs);

4)取文件

通过MinioTemplate.getObject(bucketName,objectName)获取对应的文件流,或者通过MinioTemplate.presignedObjectUrl(bucketName,objectName,时间, 时间单位)来获取有期限的文件url

4.工具类
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.*;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@AllArgsConstructor
@Slf4j
public class MinioTemplate {
    private String endpoint;
    private String accessKey;
    private String secretKey;
    private int partSize;
    private MinioClient client;
    @SneakyThrows
    public MinioTemplate(String endpoint, String accessKey, String secretKey, int partSize) {
        this.endpoint = endpoint;
        this.accessKey = accessKey;
        this.secretKey = secretKey;
        this.partSize = partSize;
        this.client = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
     * 创建bucket
     * @param bucketName bucket名称
    public void createBucket(String bucketName) throws Exception {
        if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
     * @param bucketName
     * @param days
     * @param ruleName
     * @throws Exception
    public void setBucketExpirationByDays(String bucketName,String prefix,Integer days,String ruleName) throws Exception{
        // 获取配置
        LifecycleConfiguration lifecycleConfiguration =
                client.getBucketLifecycle(
                        GetBucketLifecycleArgs
                                .builder()
                                .bucket(bucketName)
                                .build());
        List<LifecycleRule> rules = lifecycleConfiguration.rules();
        List<LifecycleRule> rulesNew = new ArrayList<>();
        rulesNew.addAll(rules);
        // 配置生命周期规则
        rulesNew.add(
                new LifecycleRule(
                        Status.ENABLED, // 开启状态
                        null,
                        new Expiration((ZonedDateTime) null, days, null), // 保存365天
                        new RuleFilter(prefix), // 目录配置
                        ruleName,
                        null,
                        null,
                        null)
        LifecycleConfiguration lifecycleConfigurationNew = new LifecycleConfiguration(rulesNew);
        // 添加生命周期配置
        client.setBucketLifecycle(
                SetBucketLifecycleArgs
                        .builder()
                        .bucket(bucketName)
                        .config(lifecycleConfigurationNew)
                        .build()
    public List<LifecycleRule> getBucketLifecycleRule(String bucketName) throws Exception{
        // 获取配置
        LifecycleConfiguration lifecycleConfiguration1111 =
                client.getBucketLifecycle(
                        GetBucketLifecycleArgs
                                .builder()
                                .bucket(bucketName)
                                .build());
        List<LifecycleRule> rules1 = lifecycleConfiguration1111.rules();
        for (LifecycleRule lifecycleRule:rules1) {
            log.debug(lifecycleRule.toString());
            log.debug("Lifecycle status is " + lifecycleRule.status()
                    +"\nLifecycle prefix is " + lifecycleRule.filter().prefix()
                    +"\nLifecycle expiration days is " + lifecycleRule.expiration().days());
        return rules1;
     * 获取全部bucket
     * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
    public List<Bucket> getAllBuckets() throws Exception {
        return client.listBuckets();
     * 根据bucketName获取信息
     * @param bucketName bucket名称
    public Optional<Bucket> getBucket(String bucketName) throws Exception {
        return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
     * 根据bucketName删除信息
     * @param bucketName bucket名称
    public void removeBucket(String bucketName) throws Exception {
        client.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
     * 分区上传文件
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param stream 文件流
     * @param size 文件大小
    public String putObject(String bucketName, String objectName, InputStream stream, Long size) throws Exception{
        PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .stream(stream, size, partSize)
                .build();
        ObjectWriteResponse objectWriteResponse = client.putObject(putObjectArgs);
        return objectWriteResponse.object();
     * 根据文件前置查询文件
     * @param bucketName bucket名称
     * @param prefix     前缀
     * @param recursive  是否递归查询
     * @return MinioItem 列表
    public List<Item> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) throws Exception {
        List<Item> objectList = new ArrayList<>();
        ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
                .bucket(bucketName)
                .prefix(prefix)
                .recursive(recursive)
                .build();
        Iterable<Result<Item>> objectsIterator = client
                .listObjects(listObjectsArgs);
        while (objectsIterator.iterator().hasNext()) {
            objectList.add(objectsIterator.iterator().next().get());
        return objectList;
     * 获取文件外链
     * 这里的 method 方法决定最后链接是什么请求获得
     *  expiry 决定这个链接多久失效
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param duration 有效大小
     * @param
     * @return url
    public String getObjectURL(String bucketName, String objectName,Integer duration, TimeUnit unit) throws Exception {
        if (null==duration||null==unit){
            duration = 7;
            unit = TimeUnit.DAYS;
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                .bucket(bucketName)
                .method(Method.GET)
                .expiry(duration, unit)
                .object(objectName)
                .build();
        return client.getPresignedObjectUrl(args);
     * 获取文件
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @return 二进制流
    public InputStream getObject(String bucketName, String objectName) throws Exception {
        GetObjectArgs getObjectArgs = GetObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();
        return client.getObject(getObjectArgs);
     * 上传文件 base64
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param base64Str 文件base64
    public String putObject(String bucketName, String objectName, String base64Str) throws Exception{
        InputStream inputStream = new ByteArrayInputStream(base64Str.getBytes());
        // 进行解码
        BASE64Decoder base64Decoder = new BASE64Decoder();
        byte[] byt = new byte[0];
        try {
            byt = base64Decoder.decodeBuffer(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        inputStream = new ByteArrayInputStream(byt);
        putObject(bucketName, objectName, inputStream, Long.valueOf(byt.length));
        return objectName;
     * 上传文件
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param file 文件
     * @throws Exception
    public String putObject( String bucketName,String objectName, MultipartFile file) throws Exception{
        this.putObject(bucketName, objectName, file.getInputStream(), file.getSize());
        return objectName;
     * 获取文件信息
     * @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 {
        StatObjectArgs statObjectArgs = StatObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();
        return client.statObject(statObjectArgs);
     * 删除文件
     * @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 {
        RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();
        client.removeObject(removeObjectArgs);
     * 根据文件名返回对应contentType
     * @param objectName
     * @return
    private String getContentType(String objectName) {
        //if(FileNameUtil.isPicture(objectName)) {
        //    return "image/jpeg";
        //if(FileNameUtil.isVideo(objectName)) {
        //    return "video/mp4";
        return null;
     * 获取直传链接
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @throws Exception
    public String presignedPutObject( String bucketName,String objectName) throws Exception{
        GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder()
                .method(Method.PUT)
                .bucket(bucketName)
                .object(objectName)
                .expiry(7, TimeUnit.DAYS)
                .build();
        return client.getPresignedObjectUrl(getPresignedObjectUrlArgs);
     * 合并文件
     * @param bucketName
     * @param chunkNames
     * @param targetObjectName
     * @return
     * @throws Exception
    public String composeObject(String bucketName, List<String> chunkNames, String targetObjectName) throws Exception{
        List<ComposeSource> sources = new ArrayList<>(chunkNames.size());
        for (String chunkName : chunkNames) {
            ComposeSource composeSource = ComposeSource.builder()
                    .bucket(bucketName)
                    .object(chunkName)
                    .build();
            sources.add(composeSource);
        ComposeObjectArgs composeObjectArgs = ComposeObjectArgs.builder()
                .bucket(bucketName)
                .sources(sources)
                .object(targetObjectName)
                .build();
        ObjectWriteResponse objectWriteResponse = client.composeObject(composeObjectArgs);
        return objectWriteResponse.object();

文件上传到minio,获取文件列表,下载文件

minio下载
以下是代码是实现
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.common.io.ByteStreams;
import com.jspxcms.ext.web.utils.PageUtil;
import com.jspxcms.ext.web.vo.FileVo;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.PutObjectOptions;
import io.minio.Result;
import io.minio.errors.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
@Controller
@RequestMapping("/file")
public class FileUploadController {
    private static MinioClient minioClient;
    // minio服务器地址
    private static final String endpoint = "http://127.0.0.1:9001";
    static {
        try {
            // minioClient初始化,设置endpoint和连接minio服务所需的密码
            minioClient = new MinioClient(endpoint, "xxx", "xxx");
        } catch (Exception e) {
            e.printStackTrace();
     * 文件上传
     * @param file       文件
     * @param bucketName 文件夹名称(minio上对应的bucket相当于文件夹)
     * @return
     * @throws Exception
    @ResponseBody
    @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String uploadFile(MultipartFile file, String bucketName) throws Exception {
        JSONObject res = new JSONObject();
        // 判断上传文件是否为空
        if (null == file || 0 == file.getSize()) {
            return "文件不能为空";
        // 判断文件夹是否存在
        boolean bucketExists = minioClient.bucketExists(bucketName);
        // 如果文件夹不存在则创建
        if (!bucketExists) {
            // 创建
            minioClient.makeBucket(bucketName);
        // 文件名
        String originalFilename = file.getOriginalFilename();
        // 上传操作
        minioClient.putObject(bucketName, originalFilename, file.getInputStream(), new PutObjectOptions(file.getSize(), 0L));
        return "文件上传成功";
     * 获取文件列表
     * @param pageNum  页码
     * @param pageSize 一页的数量
     * @return
     * @throws Exception
    @ResponseBody
    @RequestMapping(value = "/fileList", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public String getFileList(Integer pageNum, Integer pageSize) throws Exception {
        DecimalFormat df = new DecimalFormat("0.00");
        List<Bucket> buckets = minioClient.listBuckets();
        List<FileVo> list = new ArrayList<>(32);
        if (!buckets.isEmpty()) {
            buckets.forEach(s -> {
                try {
                    // 得到bucket下的文件
                    Iterable<Result<Item>> results = minioClient.listObjects(s.name());
                    // 循环遍历获取每一个文件对象
                    results.forEach(g -> {
                        try {
                            FileVo fileVo = new FileVo();
                            fileVo.setBucketName(s.name());  // 文件夹名称
                            fileVo.setFileName(g.get().objectName());  // 文件名称
                            fileVo.setUpdateTime(localDateTime2Date(g.get().lastModified().toLocalDateTime()));  // 文件上传时间
                            Long size = g.get().size();
                            if (size > (1024 * 1024)) {
                                fileVo.setFileSize(df.format(((double) size / 1024 / 1024)) + "MB");  // 文件大小,如果超过1M,则把单位换成MB
                            } else if (size > 1024) {
                                fileVo.setFileSize(df.format(((double) size / 1024)) + "KB"); // 文件大小,如果没超过1M但是超过1000字节,则把单位换成KB
                            } else {
                                fileVo.setFileSize( size + "bytes");  // // 文件大小,如果没超过1000字节,则把单位换成bytes
                            list.add(fileVo);
                        } catch (ErrorResponseException e) {
                            e.printStackTrace();
                        } catch (InsufficientDataException e) {
                            e.printStackTrace();
                        } catch (InternalException e) {
                            e.printStackTrace();
                        } catch (InvalidBucketNameException e) {
                            e.printStackTrace();
                        } catch (InvalidKeyException e) {
                            e.printStackTrace();
                        } catch (InvalidResponseException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (NoSuchAlgorithmException e) {
                            e.printStackTrace();
                        } catch (XmlParserException e) {
                            e.printStackTrace();
                    });
                } catch (XmlParserException e) {
                    e.printStackTrace();
            });
        JSONObject res = new JSONObject();
        res.put("code", 200);
        res.put("message", "获取文件列表成功");
       // 按最后上传时间排序
        list.sort(new Comparator<FileVo>() {
            @Override
            public int compare(FileVo o1, FileVo o2) {
                return o2.getUpdateTime().compareTo(o1.getUpdateTime());
        });
        // 分页
        List returnList = PageUtil.startPage(list, pageNum, pageSize);
        res.put("list", returnList);
        ObjectMapper mapper = new ObjectMapper();
        String s = mapper.writeValueAsString(res);
        return s;
     * 文件下载(浏览器端下载)
     * @param bucketName 文件夹名称
     * @param filetName  文件名称
     * @param response
     * @throws Exception
    @ResponseBody
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public void download(String bucketName, String filetName, HttpServletResponse response) throws Exception {
        // 根据文件夹名称和文件名称找到对应文件对象
        ObjectStat stat = minioClient.statObject(bucketName, filetName);
        byte[] buffer = new byte[1024];
        int length = (int) stat.length();
        try (InputStream inputStream = minioClient.getObject(bucketName, filetName);
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream(length)) {
            ByteStreams.copy(inputStream, outputStream);
            buffer = outputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-disposition", "attachment; filename=" + new String(filetName.getBytes("utf-8"), "ISO8859-1"));
        response.getOutputStream().write(buffer);
        response.flushBuffer();
        response.getOutputStream().close();
     * 删除文件
     * @param bucketName 文件夹名称
     * @param filetName  文件名称
     * @return
     * @throws Exception
    @ResponseBody
    @RequestMapping(value = "/remove", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public JSONObject removeFile(String bucketName, String filetName) throws Exception {
        // 删除文件夹下的对应文件
        minioClient.removeObject(bucketName, filetName);
        JSONObject res = new JSONObject();
        res.put("code", 200);
        res.put("message", "删除文件成功");
        return res;
     * 删除文件夹
     * @param bucketName 文件夹名称
     * @return
     * @throws Exception
    @ResponseBody
    @RequestMapping(value = "/delete.do", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public JSONObject removeBucket(String bucketName) throws Exception {
        // 删除文件夹
        minioClient.removeBucket(bucketName);
        JSONObject res = new JSONObject();
        res.put("code", 200);
        res.put("message", "删除文件夹成功");
        return res;
     * LocalDateTime转换为Date
     * @param localDateTime
    public Date localDateTime2Date( LocalDateTime localDateTime){
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        Date date = Date.from(zdt.toInstant());
        Calendar cal=Calendar.getInstance();
        cal.setTime(date);
        // 由于获取的时间存在时间差,我这里手动加上16小时
        cal.add(Calendar.HOUR_OF_DAY, 16);
        date = cal.getTime();
        return date;
FileVo
package com.jspxcms.ext.web.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class FileVo {
    private String bucketName;    //  文件夹
    private String fileName;    // 文件名
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;   // 最后修改时间
    private String fileSize;   //  文件大小
    public String getBucketName() {
        return bucketName;
    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    public String getFileName() {
        return fileName;
    public void setFileName(String fileName) {
        this.fileName = fileName;
    public Date getUpdateTime() {
        return updateTime;
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    public String getFileSize() {
        return fileSize;
    public void setFileSize(String fileSize) {
        this.fileSize = fileSize;
附上分页工具类
package com.jspxcms.ext.web.utils;
import java.util.List;
 * 自定义分页工具
public class PageUtil {
     * 开始分页
     * @param list  需要进行分页的集合列表
     * @param pageNum 页码
     * @param pageSize 每页多少条数据
     * @return
    public static List startPage(List list, Integer pageNum,
                                 Integer pageSize) {
        if (list == null) {
            return null;
        if (list.size() == 0) {
            return null;
        if(null == pageNum || "".equals(pageNum.toString())){
            pageNum = 1;
        if(null == pageSize || "".equals(pageSize.toString())){
            pageSize = 10;
        Integer count = list.size(); // 记录总数
        Integer pageCount = 0; // 页数
        if (count % pageSize == 0) {
            pageCount = count / pageSize;
        } else {
            pageCount = count / pageSize + 1;
        int fromIndex = 0; // 开始索引
        int toIndex = 0; // 结束索引
        if (pageNum != pageCount) {
            fromIndex = (pageNum - 1) * pageSize;
            toIndex = fromIndex + pageSize;
        } else {
            fromIndex = (pageNum - 1) * pageSize;
            toIndex = count;
        List pageList = list.subList(fromIndex, toIndex);
        return pageList;
                    minio Server版本:linux-amd64/minio 与 windows-amd64/minio.exeminio Client版本:linux-amd64/mc 与 windows-amd64/mc.exeminio sdk: https://dl.min.io/sdk/minio-java/官方文档:MinIO Client (mc) — MinIO祼机使用文档MinIO Server — MinIO祼机使用文档单机部署简单,使用一条指令即可启动、配置服务器节点(服务器地址,端口、api
				
赠送jar包:minio-8.0.3.jar; 赠送原API文档minio-8.0.3-javadoc.jar; 赠送源代码:minio-8.0.3-sources.jar; 赠送Maven依赖信息文件minio-8.0.3.pom; 包含翻译后的API文档minio-8.0.3-javadoc-API文档-中文(简体)版.zip; Maven坐标:io.minio:minio:8.0.3; 标签:minio中文文档、jar包、java使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用
赠送jar包:minio-8.2.2.jar; 赠送原API文档minio-8.2.2-javadoc.jar; 赠送源代码:minio-8.2.2-sources.jar; 赠送Maven依赖信息文件minio-8.2.2.pom; 包含翻译后的API文档minio-8.2.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:io.minio:minio:8.2.2; 标签:minio中文文档、jar包、java使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用
赠送jar包:minio-8.0.3.jar; 赠送原API文档minio-8.0.3-javadoc.jar; 赠送源代码:minio-8.0.3-sources.jar; 赠送Maven依赖信息文件minio-8.0.3.pom; 包含翻译后的API文档minio-8.0.3-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:io.minio:minio:8.0.3; 标签:minio、中英对照文档、jar包、java使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
用户名 密码 默认都为 minioadmin docker run -p 9090:9000 --name minio \ -v /etc/localtime:/etc/localtime \ -v /data/minio/data:/data \ -v /data/minio/config:/root/.minio \ -d minio/minio server /data 2.要设置 用户名 密码 启动项加上 -e "MINIO_ACCES
本篇文章是基于win10操作系统下载与安装MinIO文件服务器 1、下载MinIO MinIO官网:http://docs.minio.org.cn/docs/master/distributed-minio-quickstart-guide MinIO下载地址:http://docs.minio.org.cn/docs/master/minio-client-quickstart-guide 计算机网络—一个自治系统有5个局域网,其连接图如图所示。LAN2至LAN5上的主机数分别为:91,150,3,15。该自治系统分配到的IP地址块为30.138.118/23。试给出每一个局域网的地址块 54238
CSDN-Ada助手: 非常感谢博主的辛勤创作,为我们提供了如此有价值的内容。博客对Kaptcha图片验证码工具和SpringBoot整合kaptcha的实现方式进行了详细的介绍和分析,内容十分优秀。希望博主能够继续分享更多有关技术的知识,为广大技术爱好者提供更多的实用经验和技巧。作为读者,我深感受益匪浅,感谢博主的分享! 为了方便博主创作,提高生产力,CSDN上线了AI写作助手功能,就在创作编辑器右侧哦~(https://mp.csdn.net/edit?utm_source=blog_comment_recall )诚邀您来加入测评,到此(https://activity.csdn.net/creatActivity?id=10450&utm_source=blog_comment_recall)发布测评文章即可获得「话题勋章」,同时还有机会拿定制奖牌。 JAVA+VUE3.0+MINIO 大文件上传(极速上传,分片上传) 恋喵大鲤鱼: 急速上传? @PostConstruct注解详解 xuanweiace: 不太懂,为什么一定environment要静态变量呢?反正你SystemConstant都是一个@Component了,那其他地方想用,直接@Autowired 这个SystemConstant 不就可以了吗? Mybatis-Plus之四种lambda方式LambdaQueryWrapper,QueryWrapper<实体>().lambda(),LambdaQueryChainWrapper<实体> * 自定义sql 使用 * Dao层 代码: * @Select("select * from ${ew.customSqlSegment}") * List<User> selectAll(@Param(Constants.WRAPPER)Wrapper<User> wrapper); 没加表名吧