328 lines
13 KiB
Java
328 lines
13 KiB
Java
package com.zhangmeng.minio.utils;
|
||
|
||
import com.zhangmeng.minio.model.BucketFile;
|
||
import io.minio.*;
|
||
import io.minio.errors.*;
|
||
import io.minio.http.Method;
|
||
import io.minio.messages.Bucket;
|
||
import io.minio.messages.Item;
|
||
import javafx.application.Platform;
|
||
|
||
|
||
import java.io.*;
|
||
import java.security.InvalidKeyException;
|
||
import java.security.NoSuchAlgorithmException;
|
||
import java.time.ZonedDateTime;
|
||
import java.time.format.DateTimeFormatter;
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.stream.Collectors;
|
||
|
||
/**
|
||
* @author zhangmeng
|
||
* @version 1.0
|
||
* @date 2024-03-07 15:45
|
||
*/
|
||
public class MinioUtils {
|
||
|
||
private static MinioClient minioClient = null;
|
||
|
||
public static Map<String,Object> objectMap = new HashMap<>();
|
||
public static String current_bucket = "current_bucket";
|
||
public static String primaryStage = "primaryStage";
|
||
public static String bucket_choose_action_stage = "bucket_choose_action_stage";
|
||
public static String minioController = "minioController";
|
||
|
||
public static MinioClient getDefault() {
|
||
if (minioClient == null) {
|
||
Object endpoint = objectMap.get("endpoint");
|
||
Object accessKey = objectMap.get("accessKey");
|
||
Object secretKey = objectMap.get("secretKey");
|
||
if (endpoint == null ){
|
||
Platform.runLater(()->{
|
||
AlertUtils.alert_warning("配置文件:endpoint 为空");
|
||
});
|
||
return null;
|
||
}
|
||
if (accessKey == null ){
|
||
Platform.runLater(()->{
|
||
AlertUtils.alert_warning("配置文件:accessKey 为空");
|
||
});
|
||
return null;
|
||
}
|
||
|
||
if (secretKey == null ){
|
||
Platform.runLater(()->{
|
||
AlertUtils.alert_warning("配置文件:secretKey 为空");
|
||
});
|
||
return null;
|
||
}
|
||
minioClient = MinioClient.builder().endpoint(endpoint.toString()).credentials(accessKey.toString(), secretKey.toString()).build();
|
||
}
|
||
return minioClient;
|
||
}
|
||
|
||
/**
|
||
* 获得所有Bucket列表
|
||
*
|
||
* @return
|
||
*/
|
||
public static List<Bucket> getAllBuckets() {
|
||
try {
|
||
return getDefault().listBuckets();
|
||
} catch (ErrorResponseException | InsufficientDataException | InvalidKeyException | InternalException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) {
|
||
// e.printStackTrace();
|
||
Platform.runLater(()->{
|
||
AlertUtils.alert_warning("获取Bucket列表失败,请核对配置信息");
|
||
});
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 启动SpringBoot容器的时候初始化Bucket
|
||
* 如果没有Bucket则创建
|
||
*
|
||
* @param bucketName
|
||
*/
|
||
public static void createBucket(String bucketName) {
|
||
if (!bucketExists(bucketName)) {
|
||
try {
|
||
getDefault().makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||
} catch (ErrorResponseException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException | ServerException | InsufficientDataException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}else {
|
||
Platform.runLater(()->{
|
||
AlertUtils.alert_warning("bucket_name : "+ bucketName + "已存在");
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 判断Bucket是否存在,true:存在,false:不存在
|
||
*
|
||
* @param bucketName
|
||
* @return
|
||
*/
|
||
public static Boolean bucketExists(String bucketName) {
|
||
try {
|
||
return getDefault().bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||
} catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidResponseException | NoSuchAlgorithmException | XmlParserException | ServerException | IOException | InvalidKeyException e) {
|
||
e.printStackTrace();
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public String DateFormatString(ZonedDateTime zonedDateTime){
|
||
// 创建一个 DateTimeFormatter 对象,用于定义日期和时间的格式
|
||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||
// 使用 formatter 来格式化 ZonedDateTime 对象
|
||
return zonedDateTime.format(formatter);
|
||
}
|
||
|
||
/**
|
||
* 根据文件前置查询文件
|
||
*
|
||
* @param bucketName 存储桶
|
||
* @param prefix 前缀
|
||
* @param recursive 是否使用递归查询
|
||
* @return MinioItem 列表
|
||
*/
|
||
public static List<Item> getAllObjectsByPrefix(String bucketName,
|
||
String prefix,
|
||
boolean recursive) {
|
||
List<Item> list = new ArrayList<>();
|
||
Iterable<Result<Item>> objectsIterator = getDefault().listObjects(
|
||
ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
|
||
if (objectsIterator != null) {
|
||
for (Result<Item> o : objectsIterator) {
|
||
Item item = null;
|
||
try {
|
||
item = o.get();
|
||
} catch (ErrorResponseException | InsufficientDataException | InvalidKeyException |
|
||
InvalidResponseException | InternalException | IOException | NoSuchAlgorithmException |
|
||
ServerException | XmlParserException e) {
|
||
e.printStackTrace();
|
||
}
|
||
list.add(item);
|
||
}
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/**
|
||
* 获得文件外链
|
||
*
|
||
* @param bucketName
|
||
* @param objectName
|
||
* @return url
|
||
*/
|
||
public static String getPresignedObjectUrl(String bucketName, String objectName) {
|
||
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
|
||
.bucket(bucketName)
|
||
.object(objectName)
|
||
.method(Method.GET).build();
|
||
try {
|
||
return getDefault() .getPresignedObjectUrl(args);
|
||
} catch (ErrorResponseException | InsufficientDataException | InvalidKeyException | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException | IOException | InternalException e) {
|
||
e.printStackTrace();
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public static List<BucketFile> getFileList(String bucketName){
|
||
List<Item> itemList = getAllObjectsByPrefix(bucketName, null, true);
|
||
List<BucketFile> list = new ArrayList<>();
|
||
if (itemList.size() > 0 ){
|
||
list = itemList.stream().map(i -> {
|
||
BucketFile bucketFile = new BucketFile();
|
||
bucketFile.setBucketName(bucketName);
|
||
bucketFile.setDir(i.isDir());
|
||
bucketFile.setFileName(i.objectName());
|
||
bucketFile.setSize(i.size());
|
||
//获取url
|
||
String presignedObjectUrl = getPresignedObjectUrl(bucketName, i.objectName());
|
||
bucketFile.setUrl(presignedObjectUrl);
|
||
return bucketFile;
|
||
}).collect(Collectors.toList());
|
||
}
|
||
return list;
|
||
}
|
||
|
||
public static void upload_file(File file){
|
||
//文件名
|
||
String fileName = file.getName();
|
||
String newFileName = System.currentTimeMillis() + "." + getFileExtension(fileName);
|
||
String contentType = getContentType(file);
|
||
String bucketName = objectMap.get(current_bucket).toString();
|
||
if (bucketName == null){
|
||
AlertUtils.alert_warning("上传的bucket不能为空!");
|
||
return;
|
||
}
|
||
uploadFile(bucketName, file, newFileName, contentType);
|
||
}
|
||
|
||
public static String upload_file(File file,String path){
|
||
//文件名
|
||
String fileName = file.getName();
|
||
String newFileName = System.currentTimeMillis() + "." + getFileExtension(fileName);
|
||
String contentType = getContentType(file);
|
||
String bucketName = objectMap.get(current_bucket).toString();
|
||
if (bucketName == null){
|
||
AlertUtils.alert_warning("上传的bucket不能为空!");
|
||
return null;
|
||
}
|
||
uploadFile(bucketName, file, path + "/" + newFileName, contentType);
|
||
return path + "/" + newFileName;
|
||
}
|
||
|
||
|
||
public static String getContentType(File file) {
|
||
String fileName = file.getName();
|
||
String extension = getFileExtension(fileName).toLowerCase();
|
||
return switch (extension) {
|
||
case "jpg", "jpeg" -> "image/jpeg";
|
||
case "png" -> "image/png";
|
||
case "mp4" -> "video/mp4";
|
||
case "gif" -> "image/gif";
|
||
case "txt" -> "text/plain";
|
||
case "pdf" -> "application/pdf";
|
||
case "doc" -> "application/msword";
|
||
case "docx" -> "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
||
case "xls" -> "application/vnd.ms-excel";
|
||
case "xlsx" -> "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||
case "ppt" -> "application/vnd.ms-powerpoint";
|
||
case "pptx" -> "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
||
case "zip" -> "application/zip";
|
||
case "tar" -> "application/x-tar";
|
||
case "json" -> "application/json";
|
||
case "html" -> "text/html";
|
||
case "css" -> "text/css";
|
||
case "js" -> "application/javascript";
|
||
case "mp3" -> "audio/mp3";
|
||
case "wav" -> "audio/wav";
|
||
case "flac" -> "audio/flac";
|
||
case "aac" -> "audio/aac";
|
||
case "ogg" -> "audio/ogg";
|
||
case "avi" -> "video/avi";
|
||
case "mov" -> "video/quicktime";
|
||
case "wmv" -> "video/x-ms-wmv";
|
||
case "mkv" -> "video/x-matroska";
|
||
case "flv" -> "video/x-flv";
|
||
case "swf" -> "application/x-shockwave-flash";
|
||
case "psd" -> "image/vnd.adobe.photoshop";
|
||
case "ai" -> "application/postscript";
|
||
case "eps" -> "application/postscript";
|
||
case "ps" -> "application/postscript";
|
||
case "svg" -> "image/svg+xml";
|
||
case "tif" -> "image/tiff";
|
||
case "tiff" -> "image/tiff";
|
||
case "ico" -> "image/x-icon";
|
||
case "md" -> "text/markdown";
|
||
case "yaml" -> "text/yaml";
|
||
case "yml" -> "text/yaml";
|
||
case "xml" -> "text/xml";
|
||
case "csv" -> "text/csv";
|
||
case "tsv" -> "text/tab-separated-values";
|
||
case "jsonl" -> "application/json-seq";
|
||
case "bin" -> "application/octet-stream";
|
||
case "exe" -> "application/octet-stream";
|
||
case "dll" -> "application/octet-stream";
|
||
case "so" -> "application/octet-stream";
|
||
case "class" -> "application/octet-stream";
|
||
case "war" -> "application/octet-stream";
|
||
case "ear" -> "application/octet-stream";
|
||
case "rar" -> "application/octet-stream";
|
||
case "gz" -> "application/gzip";
|
||
default -> "application/octet-stream";
|
||
};
|
||
}
|
||
// 原生 Java 的等价方法
|
||
public static String getFileExtension(String fileName) {
|
||
if (fileName == null) return "";
|
||
int lastDotIndex = fileName.lastIndexOf('.');
|
||
// 判断没有点,或者点是第一个字符(例如 ".gitignore")
|
||
if (lastDotIndex == -1 || lastDotIndex == 0) {
|
||
return fileName;
|
||
}
|
||
return fileName.substring(lastDotIndex + 1);
|
||
}
|
||
|
||
/**
|
||
* 使用MultipartFile进行文件上传
|
||
*
|
||
* @param bucketName 存储桶
|
||
* @param file 文件名
|
||
* @param objectName 对象名
|
||
* @param contentType 类型
|
||
* @return
|
||
*/
|
||
public static ObjectWriteResponse uploadFile(String bucketName, File file, String objectName, String contentType) {
|
||
FileInputStream inputStream = null;
|
||
try {
|
||
inputStream = new FileInputStream(file);
|
||
return minioClient.putObject(
|
||
PutObjectArgs.builder()
|
||
.bucket(bucketName)
|
||
.object(objectName)
|
||
.contentType(contentType)
|
||
.stream(inputStream,inputStream.available(), -1)
|
||
.build());
|
||
} catch (IOException | XmlParserException | InternalException | InvalidKeyException | ErrorResponseException | ServerException | InsufficientDataException | InvalidResponseException | NoSuchAlgorithmException e) {
|
||
e.printStackTrace();
|
||
} finally {
|
||
if (inputStream != null){
|
||
try {
|
||
inputStream.close();
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
}
|