diff --git a/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/config/ObsConfig.java b/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/config/ObsConfig.java index 7649531..0867f98 100644 --- a/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/config/ObsConfig.java +++ b/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/config/ObsConfig.java @@ -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 { diff --git a/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/utils/ObsUtils.java b/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/utils/ObsUtils.java index 052d9d1..ff1056f 100644 --- a/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/utils/ObsUtils.java +++ b/bonus-modules/bonus-obs/src/main/java/com/bonus/obs/utils/ObsUtils.java @@ -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 partETags = new ArrayList<>(); + // 每个分段大小为5MB + long partSize = 5 * 1024 * 1024L; + long fileLength = file.length(); + int partCount = (int) (fileLength / partSize); + if (fileLength % partSize != 0) { + partCount++; + } + + List> 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 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 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(); + } } /** diff --git a/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/controller/OssController.java b/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/controller/OssController.java index 058ebd2..2642877 100644 --- a/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/controller/OssController.java +++ b/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/controller/OssController.java @@ -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; diff --git a/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/utils/OssUtils.java b/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/utils/OssUtils.java index fd38040..9ac2f63 100644 --- a/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/utils/OssUtils.java +++ b/bonus-modules/bonus-oss/src/main/java/com/bonus/oss/utils/OssUtils.java @@ -57,9 +57,8 @@ public class OssUtils { * @return 包含上传文件信息的结果对象 */ public R 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);