文件存储服务

This commit is contained in:
jiang 2024-07-16 16:15:33 +08:00
parent c22819d863
commit 45417dd0ec
4 changed files with 94 additions and 27 deletions

View File

@ -5,11 +5,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
*
*
* @author jiang
*/
@Configuration
@ConfigurationProperties(prefix = "obs")
public class ObsConfig {

View File

@ -5,24 +5,19 @@ import com.bonus.common.core.utils.file.FileUtils;
import com.bonus.obs.config.ObsConfig;
import com.bonus.obs.domain.ObsInfo;
import com.obs.services.ObsClient;
import com.obs.services.model.DeleteObjectResult;
import com.obs.services.model.GetObjectRequest;
import com.obs.services.model.ObsObject;
import com.obs.services.model.PutObjectResult;
import com.obs.services.model.*;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
*
*
* @author jiang
* @author bonus
*/
@Service
public class ObsUtils {
@ -51,8 +46,91 @@ public class ObsUtils {
* @return 上传结果
*/
public ObsInfo uploadFile(String objectKey, File file) {
PutObjectResult putObjectResult = obsClient.putObject(obsConfig.getBucket(), objectKey, file);
return ObsInfo.builder().bucketName(obsConfig.getBucket()).name(FileUtils.getName(objectKey)).fileType(FileUtils.getName(objectKey).substring(FileUtils.getName(objectKey).lastIndexOf('.')).toLowerCase()).length(file.length()).path(objectKey).build();
if (file.length() < 100 * 1024 * 1024L) {
obsClient.putObject(obsConfig.getBucket(), objectKey, file);
return ObsInfo.builder().bucketName(obsConfig.getBucket()).name(FileUtils.getName(objectKey)).fileType(FileUtils.getName(objectKey).substring(FileUtils.getName(objectKey).lastIndexOf('.')).toLowerCase()).length(file.length()).path(objectKey).build();
} else {
return multipartUploadFile(objectKey, file);
}
}
/**
* 分段上传文件到OBS
*
* @param objectKey 文件在OBS中的键
* @param file 要上传的文件
* @return 上传结果
*/
public ObsInfo multipartUploadFile(String objectKey, File file) {
// 创建一个固定大小为10的线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(obsConfig.getBucket(), objectKey);
InitiateMultipartUploadResult initResult = obsClient.initiateMultipartUpload(initRequest);
String uploadId = initResult.getUploadId();
List<PartEtag> partETags = new ArrayList<>();
// 每个分段大小为5MB
long partSize = 5 * 1024 * 1024L;
long fileLength = file.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
List<Future<UploadPartResult>> futures = new ArrayList<>();
for (int i = 0; i < partCount; i++) {
final int partNumber = i + 1;
final long offset = partSize * i;
final long size = Math.min(partSize, fileLength - offset);
Future<UploadPartResult> future = executorService.submit(() -> {
UploadPartRequest uploadPartRequest = new UploadPartRequest(
obsConfig.getBucket(),
objectKey,
size,
offset,
file
);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setPartNumber(partNumber);
return obsClient.uploadPart(uploadPartRequest);
});
futures.add(future);
}
for (Future<UploadPartResult> future : futures) {
UploadPartResult uploadPartResult = future.get();
partETags.add(new PartEtag(uploadPartResult.getEtag(), uploadPartResult.getPartNumber()));
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.HOURS);
// 完成分段上传
CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(
obsConfig.getBucket(),
objectKey,
uploadId,
partETags
);
obsClient.completeMultipartUpload(completeRequest);
return ObsInfo.builder()
.bucketName(obsConfig.getBucket())
.name(FileUtils.getName(objectKey))
.fileType(FileUtils.getName(objectKey).substring(FileUtils.getName(objectKey).lastIndexOf('.')).toLowerCase())
.length(file.length())
.path(objectKey)
.build();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
// 关闭线程池
executorService.shutdown();
}
}
/**

View File

@ -23,11 +23,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
*
*
* @author jiang
*/
@Slf4j
@RestController
@RequestMapping("/oss")
@ -72,8 +68,7 @@ public class OssController {
}
OSSObject ossObject = ossObjectR.getData();
// 假设这个方法进行了恰当的文件名清理和验证
String safeFileName = FileUtils.getName(objectKey);
String safeFileName = FileUtils.getName(objectKey); // 假设这个方法进行了恰当的文件名清理和验证
if (!StringUtils.hasText(safeFileName)) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
return;

View File

@ -57,9 +57,8 @@ public class OssUtils {
* @return 包含上传文件信息的结果对象
*/
public R<OssInfo> upload(String objectKey, File file) {
final long tenMegabytes = 10 * 1024 * 1024L;
try {
if (file.length() < tenMegabytes) {
if (file.length() < 10 * 1024 * 1024L) {
ossClient.putObject(ossConfig.getBucket(), objectKey, file);
} else {
ossMultipartParallelUpload(objectKey, file);