网站模板的功能,天津+交友+网站建设,wordpress实例站,什么软件可以刷网站排名MinIO 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊 S3 云存储服务接口#xff0c;非常适合于存储大容量非结构化的数据#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等#xff0c;而一个对象文件可以是任意大小#xff0c;从…MinIO 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊 S3 云存储服务接口非常适合于存储大容量非结构化的数据例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等而一个对象文件可以是任意大小从几 kb 到最大 5T 不等。
环境搭建
docker-compose搭建 # 可参考 https://docs.min.io/docs/minio-docker-quickstart-guide.html
version: 3
services:minio:image: minio/minio:latest # 原镜像minio/minio:latestcontainer_name: minio # 容器名为miniorestart: unless-stopped # 指定容器退出后的重启策略为始终重启但是不考虑在Docker守护进程启动时就已经停止了的容器volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录- ./minio/data:/data- ./minio/minio:/minio- ./minio/config:/root/.minioenvironment: # 设置环境变量,相当于docker run命令中的-eTZ: Asia/ShanghaiLANG: en_US.UTF-8MINIO_PROMETHEUS_AUTH_TYPE: publicMINIO_ACCESS_KEY: root # 登录账号MINIO_SECRET_KEY: password # 登录密码command: server /data --console-address :9001logging:driver: json-fileoptions:max-size: 100mports: # 映射端口- 9000:9000 # 文件上传预览端口- 9001:9001 # 控制台访问端口启动服务docker-compose -f docker-compose-minio.yml -p minio up -d
访问地址ip地址:9001/minio 登录账号密码root/password 一、依赖 ?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspringboot-demo/artifactIdgroupIdcom.et/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdminio/artifactIdpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-autoconfigure/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.20/version/dependencydependencygroupIdio.minio/groupIdartifactIdminio/artifactIdversion8.2.2/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.11/version/dependency/dependencies
/project二、配置文件和启动类
三、Config配置类
Data
Configuration
ConfgurationProperties(prefix minio)
public class MinioConfig{private String endpoint;private String accessKey;private String secretKey;private String bucketName;Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}四、MinioUtil工具
Slf4j
Component
RequiredArgsConstructor
public class MinioUtils {private final MinioClient minioClient;/*** 启动SpringBoot容器的时候初始化Bucket* 如果没有Bucket则创建** param bucketName*/SneakyThrows(Exception.class)private void createBucket(String bucketName) {if (!bucketExists(bucketName)) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());}}/*** 判断Bucket是否存在true存在false不存在** param bucketName* return*/SneakyThrows(Exception.class)public boolean bucketExists(String bucketName) {return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());}/*** 获得Bucket的策略** param bucketName* return*/SneakyThrows(Exception.class)public String getBucketPolicy(String bucketName) {return minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket(bucketName).build());}/*** 获得所有Bucket列表** return*/SneakyThrows(Exception.class)public ListBucket getAllBuckets() {return minioClient.listBuckets();}/*** 根据bucketName获取其相关信息** param bucketName* return*/SneakyThrows(Exception.class)public OptionalBucket getBucket(String bucketName) {return getAllBuckets().stream().filter(b - b.name().equals(bucketName)).findFirst();}/*** 根据bucketName删除Buckettrue删除成功 false删除失败文件或已不存在** param bucketName* throws Exception*/SneakyThrows(Exception.class)public void removeBucket(String bucketName) {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());}/*** 判断文件是否存在** param bucketName* param objectName* return*/public boolean isObjectExist(String bucketName, String objectName) {boolean exist true;try {minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());} catch (Exception e) {log.error([Minio工具类] 判断文件是否存在, 异常, e);exist false;}return exist;}/*** 判断文件夹是否存在** param bucketName* param objectName* return*/public boolean isFolderExist(String bucketName, String objectName) {boolean exist false;try {IterableResultItem results minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());for (ResultItem result : results) {Item item result.get();if (item.isDir() objectName.equals(item.objectName())) {exist true;}}} catch (Exception e) {log.error([Minio工具类] 判断文件夹是否存在异常, e);exist false;}return exist;}/*** 根据文件前置查询文件** param bucketName 存储桶* param prefix 前缀* param recursive 是否使用递归查询* return MinioItem 列表*/SneakyThrows(Exception.class)public ListItem getAllObjectsByPrefix(String bucketName,String prefix,boolean recursive) {ListItem list new ArrayList();IterableResultItem objectsIterator minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());if (objectsIterator ! null) {for (ResultItem o : objectsIterator) {Item item o.get();list.add(item);}}return list;}/*** 获取文件流** param bucketName 存储桶* param objectName 文件名* return 二进制流*/SneakyThrows(Exception.class)public InputStream getObject(String bucketName, String objectName) {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());}/*** 断点下载** param bucketName 存储桶* param objectName 文件名称* param offset 起始字节的位置* param length 要读取的长度* return 二进制流*/SneakyThrows(Exception.class)public InputStream getObject(String bucketName, String objectName, long offset, long length) {return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).offset(offset).length(length).build());}/*** 获取路径下文件列表** param bucketName 存储桶* param prefix 文件名称* param recursive 是否递归查找false模拟文件夹结构查找* return 二进制流*/public IterableResultItem listObjects(String bucketName, String prefix, boolean recursive) {return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());}/*** 使用MultipartFile进行文件上传** param bucketName 存储桶* param file 文件名* param objectName 对象名* param contentType 类型* return*/SneakyThrows(Exception.class)public ObjectWriteResponse uploadFile(String bucketName, MultipartFile file, String objectName, String contentType) {InputStream inputStream file.getInputStream();return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).contentType(contentType).stream(inputStream, inputStream.available(), -1).build());}/*** 图片上传* param bucketName* param imageBase64* param imageName* return*/public ObjectWriteResponse uploadImage(String bucketName, String imageBase64, String imageName) {if (!StringUtils.isEmpty(imageBase64)) {InputStream in base64ToInputStream(imageBase64);String newName System.currentTimeMillis() _ imageName .jpg;String year String.valueOf(new Date().getYear());String month String.valueOf(new Date().getMonth());return uploadFile(bucketName, year / month / newName, in);}return null;}public static InputStream base64ToInputStream(String base64) {ByteArrayInputStream stream null;try {byte[] bytes new BASE64Decoder().decodeBuffer(base64.trim());stream new ByteArrayInputStream(bytes);} catch (Exception e) {e.printStackTrace();}return stream;}/*** 上传本地文件** param bucketName 存储桶* param objectName 对象名称* param fileName 本地文件路径* return*/SneakyThrows(Exception.class)public ObjectWriteResponse uploadFile(String bucketName, String objectName, String fileName) {return minioClient.uploadObject(UploadObjectArgs.builder().bucket(bucketName).object(objectName).filename(fileName).build());}/*** 通过流上传文件** param bucketName 存储桶* param objectName 文件对象* param inputStream 文件流* return*/SneakyThrows(Exception.class)public ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) {return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(inputStream, inputStream.available(), -1).build());}/*** 创建文件夹或目录** param bucketName 存储桶* param objectName 目录路径* return*/SneakyThrows(Exception.class)public ObjectWriteResponse createDir(String bucketName, String objectName) {return minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(new ByteArrayInputStream(new byte[]{}), 0, -1).build());}/*** 获取文件信息, 如果抛出异常则说明文件不存在** param bucketName 存储桶* param objectName 文件名称* return*/SneakyThrows(Exception.class)public String getFileStatusInfo(String bucketName, String objectName) {return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build()).toString();}/*** 拷贝文件** param bucketName 存储桶* param objectName 文件名* param srcBucketName 目标存储桶* param srcObjectName 目标文件名*/SneakyThrows(Exception.class)public ObjectWriteResponse copyFile(String bucketName, String objectName, String srcBucketName, String srcObjectName) {return minioClient.copyObject(CopyObjectArgs.builder().source(CopySource.builder().bucket(bucketName).object(objectName).build()).bucket(srcBucketName).object(srcObjectName).build());}/*** 删除文件** param bucketName 存储桶* param objectName 文件名称*/SneakyThrows(Exception.class)public void removeFile(String bucketName, String objectName) {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());}/*** 批量删除文件** param bucketName 存储桶* param keys 需要删除的文件列表* return*/public void removeFiles(String bucketName, ListString keys) {ListDeleteObject objects new LinkedList();keys.forEach(s - {objects.add(new DeleteObject(s));try {removeFile(bucketName, s);} catch (Exception e) {log.error([Minio工具类] 批量删除文件异常, e);}});}/*** 获取文件外链** param bucketName 存储桶* param objectName 文件名* param expires 过期时间 7 秒 外链有效时间单位秒* return url*/SneakyThrows(Exception.class)public String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) {GetPresignedObjectUrlArgs args GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName).object(objectName).build();return minioClient.getPresignedObjectUrl(args);}/*** 获得文件外链** param bucketName* param objectName* return url*/SneakyThrows(Exception.class)public String getPresignedObjectUrl(String bucketName, String objectName) {GetPresignedObjectUrlArgs args GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).method(Method.GET).build();return minioClient.getPresignedObjectUrl(args);}/*** 将URLDecoder编码转成UTF8** param str* return* throws UnsupportedEncodingException*/public String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {String url str.replaceAll(%(?![0-9a-fA-F]{2}), %25);return URLDecoder.decode(url, UTF-8);}
}五、Controller接口
Slf4j
RestController
RequestMapping(/oss)
public class OSSController {Autowiredprivate MinioUtils minioUtils;Autowiredprivate MinioConfig minioConfig;/*** 文件上传** param file*/PostMapping(/upload)public String upload(RequestParam(file) MultipartFile file) {try {//文件名String fileName file.getOriginalFilename();String newFileName System.currentTimeMillis() . StringUtils.substringAfterLast(fileName, .);//类型String contentType file.getContentType();minioUtils.uploadFile(minioConfig.getBucketName(), file, newFileName, contentType);return 上传成功;} catch (Exception e) {e.printStackTrace();log.error(上传失败);return 上传失败;}}/*** 删除** param fileName*/DeleteMapping(/)public void delete(RequestParam(fileName) String fileName) {minioUtils.removeFile(minioConfig.getBucketName(), fileName);}/*** 获取文件信息** param fileName* return*/GetMapping(/info)public String getFileStatusInfo(RequestParam(fileName) String fileName) {return minioUtils.getFileStatusInfo(minioConfig.getBucketName(), fileName);}/*** 获取文件外链** param fileName* return*/GetMapping(/url)public String getPresignedObjectUrl(RequestParam(fileName) String fileName) {return minioUtils.getPresignedObjectUrl(minioConfig.getBucketName(), fileName);}/*** 文件下载** param fileName* param response*/GetMapping(/download)public void download(RequestParam(fileName) String fileName, HttpServletResponse response) {try {InputStream fileInputStream minioUtils.getObject(minioConfig.getBucketName(), fileName);response.setHeader(Content-Disposition, attachment;filename fileName);response.setContentType(application/force-download);response.setCharacterEncoding(UTF-8);IOUtils.copy(fileInputStream, response.getOutputStream());} catch (Exception e) {log.error(下载失败);}}
}测试
我们使用postman来测试一下上传接口测试成功了 也可以在登录minio后台查看我们刚刚上传的文件