一、minio简介

MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储。 它是与 Amazon S3 云存储服务兼容的 API,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等

二、minio安装

参考我的另一篇文章:https://www.cnblogs.com/lvlinguang/p/15770479.html

一、java中使用

1、pom文件引用

<!-- minio 文件服务客户端 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>6.0.11</version>
</dependency>

2、添加配置文件

  • url:minio服务器的接口地址,不是访问地址
  • accessKey/secretKey:登录minio系统,新建Service Accounts
config:
minio:
url: http://192.168.3.15:9000
accessKey: 66SBZWYDSO0DZRSE1U3T
secretKey: S+p8mWE8aykZ0YsRtC0ef35qUS7fUbkITITJdjS6

3、注册MinioClient

@Data
@Configuration
@ConfigurationProperties(prefix = "config.minio")
public class MinioConfig {
/**
* minio 服务地址 http://ip:port
*/
private String url; /**
* 用户名
*/
private String accessKey; /**
* 密码
*/
private String secretKey; @SneakyThrows
@Bean
@RefreshScope
public MinioClient minioClient(){
return new MinioClient(url, accessKey, secretKey);
}
}

4、minio工具类

/**
* minio工具类
*
* @author lvlinguang
* @date 2022-01-07 12:26
* @see http://docs.minio.org.cn/docs/master/java-client-api-reference
*/
@Component
public class MinioUtils { @Autowired
private MinioClient client; /**
* 创建bucket
*
* @param bucketName
*/
@SneakyThrows
public void createBucket(String bucketName) {
if (!client.bucketExists(bucketName)) {
client.makeBucket(bucketName);
}
} /**
* 获取所有bucket
*
* @return
*/
@SneakyThrows
public List<Bucket> listAllBuckets() {
return client.listBuckets();
} /**
* bucket详情
*
* @param bucketName 名称
* @return
*/
@SneakyThrows
public Optional<Bucket> getBucket(String bucketName) {
return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
} /**
* 删除bucket
*
* @param bucketName 名称
*/
@SneakyThrows
public void removeBucket(String bucketName) {
client.removeBucket(bucketName);
} /**
* 上传文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param stream 文件流
* @throws Exception
*/
@SneakyThrows
public void uploadFile(String bucketName, String objectName, InputStream stream) throws Exception {
this.uploadFile(bucketName, objectName, stream, (long) stream.available(), "application/octet-stream");
} /**
* 上传文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param stream 文件流
* @param size 大小
* @param contextType 类型
* @throws Exception
*/
@SneakyThrows
public void uploadFile(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {
//如果bucket不存在,则创建
this.createBucket(bucketName);
client.putObject(bucketName, objectName, stream, size, null, null, contextType);
} /**
* 获取文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @return
*/
@SneakyThrows
public InputStream getFile(String bucketName, String objectName) {
return client.getObject(bucketName, objectName);
} /**
* 根据文件前置查询文件
*
* @param bucketName bucket名称
* @param prefix 前缀
* @param recursive 是否递归查询
* @return
*/
@SneakyThrows
public List<MinioItem> listAllFileByPrefix(String bucketName, String prefix, boolean recursive) {
List<MinioItem> objectList = new ArrayList<>();
Iterable<Result<Item>> objectsIterator = client
.listObjects(bucketName, prefix, recursive);
while (objectsIterator.iterator().hasNext()) {
objectList.add(new MinioItem(objectsIterator.iterator().next().get()));
}
return objectList;
} /**
* 删除文件
*
* @param bucketName bucket名称
* @param objectName 文件名称
*/
@SneakyThrows
public void removeFile(String bucketName, String objectName) {
client.removeObject(bucketName, objectName);
} /**
* 获取文件外链
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @param expires 过期时间 <=7
* @return
*/
@SneakyThrows
public String getFileURL(String bucketName, String objectName, Integer expires) {
return client.presignedGetObject(bucketName, objectName, expires);
} /**
* 获取文件信息
*
* @param bucketName bucket名称
* @param objectName 文件名称
* @return
*/
@SneakyThrows
public ObjectStat getFileInfo(String bucketName, String objectName) {
return client.statObject(bucketName, objectName);
}
}

5、文件操作类

/**
* 系统文件工具类
*
* @author lvlinguang
* @date 2021-02-28 12:30
*/
@Component
public class SysFileUtils { /**
* 文件服务器中的目录分隔符
*/
public static final String SEPRETOR = "/"; @Autowired
private MinioUtils minioUtils; /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @return
*/
@SneakyThrows
public MinioObject uploadFile(MultipartFile object, String bucketName) {
return this.uploadFile(object.getInputStream(), bucketName, object.getOriginalFilename());
} /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @param fileName 文件名
* @return
*/
@SneakyThrows
public MinioObject uploadFile(MultipartFile object, String bucketName, String fileName) {
return this.uploadFile(object.getInputStream(), bucketName, fileName);
} /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @param randomFileName 文件名是否随机(是:按年/月/日/随机值储存,否:按原文件名储存)
* @return
*/
@SneakyThrows
public MinioObject uploadFile(MultipartFile object, String bucketName, Boolean randomFileName) {
//文件名
String fileName = object.getOriginalFilename();
if (randomFileName) {
//扩展名
String extName = FileUtil.extName(object.getOriginalFilename());
if (StrUtil.isNotBlank(extName)) {
extName = StrUtil.DOT + extName;
}
//新文件名
fileName = randomFileName(extName);
}
return this.uploadFile(object.getInputStream(), bucketName, fileName);
} /**
* 文件上传
*
* @param object 文件对你
* @param bucketName bucket名称
* @param fileName 文件名
* @return
*/
@SneakyThrows
public MinioObject uploadFile(InputStream object, String bucketName, String fileName) {
try {
minioUtils.uploadFile(bucketName, fileName, object);
return new MinioObject(minioUtils.getFileInfo(bucketName, fileName));
} catch (Exception e) {
throw new Exception(e);
} finally {
if (object != null) {
object.close();
}
}
} /**
* 下载文件
*
* @param response response
* @param url 文件地址(/bucketName/fileName)
*/
public void downloadFile(HttpServletResponse response, String url) {
final String bucketName = getBucketName(url);
final String filePath = getFilePath(url);
this.downloadFile(response, bucketName, filePath);
} /**
* 下载文件
*
* @param response response
* @param bucket bucket名称
* @param fileName 文件名
*/
public void downloadFile(HttpServletResponse response, String bucket, String fileName) {
try (InputStream inputStream = minioUtils.getFile(bucket, fileName)) {
if ("jpg".equals(FileUtil.extName(fileName))) {
response.setContentType("image/jpeg");
} else if ("png".equals(FileUtil.extName(fileName))) {
response.setContentType("image/png");
} else {
response.setContentType("application/octet-stream; charset=UTF-8");
}
IoUtil.copy(inputStream, response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
} /**
* 获取链接地址的 文件名
*
* @param bucketFileUrl
* @return
*/
public static String getFilePath(String bucketFileUrl) {
if (bucketFileUrl == null) {
return null;
}
//去掉第一个分割符
if (bucketFileUrl.startsWith(SEPRETOR)) {
bucketFileUrl = bucketFileUrl.substring(1);
}
return bucketFileUrl.substring(bucketFileUrl.indexOf(SEPRETOR) + 1);
} /**
* 获取链接地址的 bucketName
*
* @param bucketFileUrl 地址(/{bucketName}/{path}/{fileName})
* @return
*/
public static String getBucketName(String bucketFileUrl) {
if (bucketFileUrl == null) {
return null;
}
//去掉第一个分割符
if (bucketFileUrl.startsWith(SEPRETOR)) {
bucketFileUrl = bucketFileUrl.substring(1);
}
return bucketFileUrl.substring(0, bucketFileUrl.indexOf(SEPRETOR));
} /**
* 生成新的文件名
*
* @param extName 扩展名
* @return
*/
public static String randomFileName(String extName) {
LocalDate now = LocalDate.now();
return now.getYear() + SEPRETOR +
getFullNumber(now.getMonthValue()) + SEPRETOR +
getFullNumber(now.getDayOfMonth()) + SEPRETOR +
UUID.randomUUID().toString().replace("-", "") + extName;
} /**
* 得到数字全称,带0
*
* @param number
* @return
*/
public static String getFullNumber(Integer number) {
if (number < 10) {
return "0" + number;
}
return number.toString();
}
}

5、返回包装类

@Data
public class MinioItem { private String objectName;
private Date lastModified;
private String etag;
private Long size;
private String storageClass;
private Owner owner;
private String type; public MinioItem(Item item) {
this.objectName = item.objectName();
this.lastModified = item.lastModified();
this.etag = item.etag();
this.size = (long) item.size();
this.storageClass = item.storageClass();
this.owner = item.owner();
this.type = item.isDir() ? "directory" : "file";
}
} @Data
public class MinioObject { private String bucketName;
private String name;
private Date createdTime;
private Long length;
private String etag;
private String contentType; public MinioObject(ObjectStat os) {
this.bucketName = os.bucketName();
this.name = os.name();
this.createdTime = os.createdTime();
this.length = os.length();
this.etag = os.etag();
this.contentType = os.contentType();
}
}

6、控制器调用

@RestController
@RequestMapping("/file")
public class FileController { public static final String MAPPING = "/file"; @Autowired
private SysFileUtils sysFileUtils; @PostMapping("/upload")
public ApiResponse<MinioObject> upload(@RequestPart("file") MultipartFile file, @RequestParam("bucketName") String bucketName) {
final MinioObject minioObject = sysFileUtils.uploadFile(file, bucketName, true);
return ApiResponse.ok(minioObject);
} @GetMapping("/info/**")
public void getFile(HttpServletRequest request, HttpServletResponse response) {
final String uri = request.getRequestURI();
String fullName = uri.replace(MAPPING + "/info", "");
sysFileUtils.downloadFile(response, fullName);
}
}

7、访问测试

  • 上传测试

-下载/访问测试

地址:http://192.168.3.15:30061/info/avatar/2022/01/07/41aaeb9f56e64c10971b2d9c675ce8fe.jpg

minio文件上传与下载的更多相关文章

  1. java web学习总结(二十四) -------------------Servlet文件上传和下载的实现

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  2. (转载)JavaWeb学习总结(五十)——文件上传和下载

    源地址:http://www.cnblogs.com/xdp-gacl/p/4200090.html 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传 ...

  3. JavaWeb学习总结,文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  4. java文件上传和下载

    简介 文件上传和下载是java web中常见的操作,文件上传主要是将文件通过IO流传放到服务器的某一个特定的文件夹下,而文件下载则是与文件上传相反,将文件从服务器的特定的文件夹下的文件通过IO流下载到 ...

  5. 使用jsp/servlet简单实现文件上传与下载

    使用JSP/Servlet简单实现文件上传与下载    通过学习黑马jsp教学视频,我学会了使用jsp与servlet简单地实现web的文件的上传与下载,首先感谢黑马.好了,下面来简单了解如何通过使用 ...

  6. JavaWeb学习总结(五十)——文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  7. 文件上传和下载(可批量上传)——Spring(三)

    在文件上传和下载(可批量上传)——Spring(二)的基础上,发现了文件下载时,只有在Chrome浏览器下文件名正常显示,还有发布到服务器后,不能上传到指定的文件夹目录,如上传20160310.txt ...

  8. 文件上传和下载(可批量上传)——Spring(二)

    针对SpringMVC的文件上传和下载.下载用之前“文件上传和下载——基础(一)”的依然可以,但是上传功能要修改,这是因为springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置 ...

  9. Struts2 之 实现文件上传和下载

    Struts2  之 实现文件上传和下载 必须要引入的jar commons-fileupload-1.3.1.jar commons-io-2.2.jar 01.文件上传需要分别在struts.xm ...

随机推荐

  1. git 使用https方式进行 pull、push代码免密

    由于网络原因我用ssh方法拉取代码每次都提示远程服务连接失败,因此我用了https方式去拉去代码. 这种方式拉取代码每次操作都要输入密码,为了解决这个问题做了一下操作: 在命令行输入 git conf ...

  2. 【力扣】649. Dota2 参议院

    Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇) Dota2 参议院由来自两派的参议员组成.现在参议院希望对一个 Dota2 游戏里的改变作出决定.他们以一个基于轮为过程的投 ...

  3. RocketMQ架构原理解析(三):消息索引

    一.概述 "索引"一种数据结构,帮助我们快速定位.查询数据 前文我们梳理了消息在Commit Log文件的存储过程,讨论了消息的落盘策略,然而仅仅通过Commit Log存储消息是 ...

  4. centos部署代码仓库gitlab

    目录 一.简介 二.程序部署 部署gitlab 汉化gitlab 三.设置管理员密码 网页方式 指令方式 一.简介 GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托 ...

  5. inode节点

    目录 一.简介 二.信息 inode的内容 inode的大小 3.inode号码 三.目录文件 四.硬连接 五.软链接 六.inode的特殊作用 一.简介 理解inode,要从文件储存说起. 文件储存 ...

  6. 象群游牧算法-Matlab

    1. 适应度函数: function z=chaffer(x)%chaffer函数x=(0...0) f(x)=0 x[-10,10]%%没测 n=10; s1=0; for i=1:n s1=s1+ ...

  7. git 基本命令及idea集成使用

    目录 git基本命令使用 设置签名 gitHub 服务配置秘钥 上传代码 更新代码 分支管理 bat脚本更新 idea集成git git基本命令使用 设置签名 签名和秘钥大多数是一起设置的,设置后一般 ...

  8. CF935B Fafa and the Gates 题解

    Content 一个动点 \(F\) 一开始在平面直角坐标系上原点的位置,随后它会移动 \(n\) 次,每次只能向上走或者向右走 \(1\) 个单位,求经过直线 \(y=x\) 的次数. 数据范围:\ ...

  9. java 多线程 读写互斥锁ReentrantReadWriteLock:读读不互斥,读写互斥,写写互斥

    ReentrantReadWriteLock: 类ReentrantLock具有相互互斥的排他效果,也就是说,同一时间,只有一个线程执行lock()方法后面的任务.这样做虽然可以解决问题,但是效率非常 ...

  10. pycharm字体放大的设置

    一.pycharm字体放大的设置 File -> setting -> Keymap ->在搜寻框中输入:increase -> Increase Font Size(双击) ...