Files
aliyun-oss-springboot-starter/src/main/java/com/njcn/ali/oss/util/AliYunOssUtils.java
2026-01-13 16:01:11 +08:00

292 lines
10 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.njcn.ali.oss.util;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.*;
import com.njcn.ali.oss.config.AliYunOssConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.*;
import java.net.URL;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* 阿里云OSS核心工具类
* 封装常用操作上传、下载、删除、查询、生成临时访问URL等
*
* @author web2023
*/
@Component
public class AliYunOssUtils {
private static final Logger logger = LoggerFactory.getLogger(AliYunOssUtils.class);
@Resource
private OSS ossClient;
@Resource
private AliYunOssConfig ossConfig;
/**
* 上传文件(字节数组)
*
* @param objectName 文件在OSS中的路径/名称
* @param content 文件字节数组
* @return 上传结果ETag
*/
public String uploadFile(String objectName, byte[] content) {
return uploadFile(objectName, new ByteArrayInputStream(content));
}
/**
* 上传文件InputStream
*
* @param objectName 文件在OSS中的路径/名称
* @param inputStream 文件输入流
* @return 上传结果ETag
*/
public String uploadFile(String objectName, InputStream inputStream) {
try {
PutObjectResult result = ossClient.putObject(
ossConfig.getBucket(),
objectName,
inputStream
);
return result.getETag();
} catch (Exception e) {
logger.error("文件{}上传失败", objectName, e);
throw new RuntimeException("文件上传失败:" + objectName, e);
}
}
/**
* 上传文件MultipartFile
*
* @param objectName 文件在OSS中的路径/名称
* @param multipartFile 文件输入流
* @return 上传结果ETag
*/
public String uploadFile(String objectName, MultipartFile multipartFile) {
try {
PutObjectResult result = ossClient.putObject(
ossConfig.getBucket(),
objectName,
multipartFile.getInputStream()
);
return result.getETag();
} catch (Exception e) {
logger.error("文件{}上传失败", objectName, e);
throw new RuntimeException("文件上传失败:" + objectName, e);
}
}
/**
* 上传本地文件
*
* @param objectName 文件在OSS中的路径/名称
* @param localFilePath 本地文件路径
* @return 上传结果ETag
*/
public String uploadLocalFile(String objectName, String localFilePath) {
File file = new File(localFilePath);
if (!file.exists()) {
throw new RuntimeException("本地文件不存在:" + localFilePath);
}
try {
PutObjectResult result = ossClient.putObject(
ossConfig.getBucket(),
objectName,
file
);
return result.getETag();
} catch (Exception e) {
logger.error("本地文件{}上传失败", localFilePath, e);
throw new RuntimeException("本地文件上传失败:" + localFilePath, e);
}
}
/**
* 下载文件到本地
*
* @param objectName OSS中的文件名称/路径
* @param localFilePath 本地保存路径
*/
public void downloadFile(String objectName, String localFilePath) {
try {
ossClient.getObject(
new GetObjectRequest(ossConfig.getBucket(), objectName),
new File(localFilePath)
);
} catch (Exception e) {
logger.error("文件{}下载失败", objectName, e);
throw new RuntimeException("文件下载失败:" + objectName, e);
}
}
/**
* 下载文件为字节流
*
* @param objectName OSS中的文件名称/路径
* @return 文件字节流
*/
public InputStream downloadStream(String objectName) {
try {
OSSObject ossObject = ossClient.getObject(ossConfig.getBucket(), objectName);
InputStream inputStream = ossObject.getObjectContent();
return inputStream;
} catch (Exception e) {
logger.error("文件{}下载为字节数组失败", objectName, e);
throw new RuntimeException("文件下载为字节数组失败:" + objectName, e);
}
}
/**
* 下载文件为字节数组
*
* @param objectName OSS中的文件名称/路径
* @return 文件字节数组
*/
public byte[] downloadFileToBytes(String objectName) {
try {
OSSObject ossObject = ossClient.getObject(ossConfig.getBucket(), objectName);
InputStream inputStream = ossObject.getObjectContent();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
return outputStream.toByteArray();
} catch (Exception e) {
logger.error("文件{}下载为字节数组失败", objectName, e);
throw new RuntimeException("文件下载为字节数组失败:" + objectName, e);
}
}
/**
* 下载文件为文件
*
* @param folderPath OSS中的文件名称/路径
* @return 文件
*/
public File getLastFile(String folderPath) {
try {
// 列出文件夹下所有文件(分页处理,避免文件过多)
ObjectListing objectListing = ossClient.listObjects(ossConfig.getBucket(), folderPath);
List<OSSObjectSummary> objectSummaries = objectListing.getObjectSummaries();
// 处理空文件夹
if (objectSummaries.isEmpty()) {
logger.warn("OSS文件夹 {} 下无文件", folderPath);
return null;
}
// 按最后修改时间降序排序,取第一个(最新)
String latestFileName = objectSummaries.stream()
.filter(summary -> !summary.getKey().equals(folderPath))
.max(Comparator.comparing(OSSObjectSummary::getLastModified))
.map(OSSObjectSummary::getKey)
.orElse(null);
if (ObjUtil.isNull(latestFileName)) {
throw new RuntimeException("OSS文件夹 " + folderPath + " 下无可用文件");
}
File file = File.createTempFile(latestFileName.split(".xlsx")[0], ".xlsx");
InputStream inputStream = ossClient.getObject(ossConfig.getBucket(), latestFileName).getObjectContent();
FileUtil.writeFromStream(inputStream, file);
inputStream.close();
return file;
} catch (Exception e) {
logger.error("查找OSS文件夹 {} 最新文件失败", folderPath, e);
throw new RuntimeException("查找最新文件失败:" + folderPath, e);
}
}
/**
* 删除单个文件
*
* @param objectName OSS中的文件名称/路径
*/
public void deleteFile(String objectName) {
try {
VoidResult voidResult = ossClient.deleteObject(ossConfig.getBucket(), objectName);
ResponseMessage response = voidResult.getResponse();
System.out.println(response);
} catch (Exception e) {
logger.error("文件{}删除失败", objectName, e);
throw new RuntimeException("文件删除失败:" + objectName, e);
}
}
/**
* 批量删除文件
*
* @param objectNames 文件名称列表
*/
public void deleteFiles(List<String> objectNames) {
try {
// 静默删除,不返回删除结果
DeleteObjectsRequest request = new DeleteObjectsRequest(ossConfig.getBucket())
.withKeys(objectNames);
ossClient.deleteObjects(request);
} catch (Exception e) {
logger.error("批量删除文件失败", e);
throw new RuntimeException("批量删除文件失败", e);
}
}
/**
* 判断文件是否存在
*
* @param objectName OSS中的文件名称/路径
* @return true-存在false-不存在
*/
public boolean isFileExist(String objectName) {
try {
boolean exists = ossClient.doesObjectExist(ossConfig.getBucket(), objectName);
return exists;
} catch (Exception e) {
logger.error("判断文件{}是否存在失败", objectName, e);
throw new RuntimeException("判断文件是否存在失败:" + objectName, e);
}
}
/**
* 生成文件临时访问URL
*
* @param objectName OSS中的文件名称/路径
* @param expireSeconds 过期时间(秒)
* @return 临时访问URL
*/
public String generatePresignedUrl(String objectName, int expireSeconds) {
try {
Date expiration = new Date(System.currentTimeMillis() + expireSeconds * 1000L);
URL url = ossClient.generatePresignedUrl(
ossConfig.getBucket(),
objectName,
expiration
);
String urlStr = url.toString();
logger.info("文件{}生成临时访问URL成功过期时间{}秒", objectName, expireSeconds);
return urlStr;
} catch (Exception e) {
logger.error("生成文件{}临时访问URL失败", objectName, e);
throw new RuntimeException("生成临时访问URL失败" + objectName, e);
}
}
/**
* 关闭OSS客户端
*/
public void close() {
if (ossClient != null) {
ossClient.shutdown();
logger.info("OSS客户端已关闭");
}
}
}