package com.medicine.management_side.utils;
import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class OSSMultipartUploadUtil {
private static String ACCESS_ID = "";
private static String ACCESS_KEY = "";
private static String OSS_ENDPOINT = "";
private static long PART_SIZE = 1 * 1024 * 1024L; // 每个Part的大小,最小为1M
private static int CONCURRENCIES = 2; // 上传Part的并发线程数。
private static String partUrl = "";
private static String bucketName = ""; // 需要存储的bucketName
private static String picLocation = "bigFile/"; // 图片保存路径
static {
try {
Resource resource = new ClassPathResource("/application.properties");
Properties props = PropertiesLoaderUtils.loadProperties(resource);
if("0".equals(props.getProperty("isnable").toString())){
Resource resourceTest = new ClassPathResource("/oss.properties");
Properties propsTest = PropertiesLoaderUtils.loadProperties(resourceTest);
OSS_ENDPOINT = propsTest.getProperty("endpoint").toString();
//System.out.println("ttttttttttttttttt111"+OSS_ENDPOINT);
ACCESS_ID = propsTest.getProperty("accessKeyId").toString();
ACCESS_KEY = propsTest.getProperty("accessKeySecret").toString();
bucketName = propsTest.getProperty("bucketName").toString();
}else if("1".equals(props.getProperty("isnable").toString())){
Resource resourceArea = new ClassPathResource("/oss.properties");
Properties propsArea = PropertiesLoaderUtils.loadProperties(resourceArea);
OSS_ENDPOINT = propsArea.getProperty("endpointn").toString();//青岛内网
// System.out.println("222222222222222222222"+OSS_ENDPOINT);
ACCESS_ID = propsArea.getProperty("accessKeyId").toString();
ACCESS_KEY = propsArea.getProperty("accessKeySecret").toString();
bucketName = propsArea.getProperty("bucketName").toString();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 分段上传大文件,同时返回 原图和缩略图 通过Multipart的方式上传一个大文件,要上传文件的大小必须大于一个Part允许的最小大小,即5MB。
* @throws OSSException
* @throws ClientException
* @throws InterruptedException
*/
public static PageData uploadBigFileAndOssUplodeSingdUrl(MultipartFile file,String filename) throws OSSException, ClientException, InterruptedException {
long begin = System.currentTimeMillis();
ClientConfiguration config = new ClientConfiguration();
config.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
config.setSocketTimeout(15 * 1000);// socket超时,默认15秒
config.setMaxConnections(10); // // 设置HTTP最大连接数为10
config.setMaxErrorRetry(2);// 失败后最大重试次数
OSSClient client = new OSSClient(OSS_ENDPOINT, ACCESS_ID, ACCESS_KEY, config);
// OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret,conf);
//String key = String.format("%s%s.%s",picLocation,UuidUtil.get32UUID(),fileTypeName);
String key = "patient/"+filename;
int partCount = calPartCount(file.getSize());
// System.out.println("partCountpartCountpartCountpartCount"+partCount);
if (partCount <= 1) {
throw new IllegalArgumentException("要上传文件的大小必须大于一个Part的字节数:" + PART_SIZE);
}
String uploadId = initMultipartUpload(client,bucketName, key);
ExecutorService pool = Executors.newFixedThreadPool(CONCURRENCIES);
List<PartETag> eTags = Collections.synchronizedList(new ArrayList<PartETag>());
for (int i = 0; i < partCount; i++) {
long start = PART_SIZE * i;
long curPartSize = PART_SIZE < file.getSize() - start ? PART_SIZE : file.getSize() - start;
pool.execute(new UploadPartThread(client,bucketName, key,file, uploadId, i + 1, PART_SIZE * i, curPartSize,eTags));
}
pool.shutdown();
while (!pool.isTerminated()) {
pool.awaitTermination(5, TimeUnit.SECONDS);
}
if (eTags.size() != partCount) {
throw new IllegalStateException("Multipart上传失败,有Part未上传成功。");
}
completeMultipartUpload(client,bucketName, key, uploadId, eTags);
String fileUrl = "";
long end = System.currentTimeMillis();
// System.out.println(end - begin);
Date expiration = new Date(new Date().getTime() + 3600l*1000*24*365*100);
// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
fileUrl = client.generatePresignedUrl(bucketName, key, expiration).toString().replace("-internal", "");
// 将图片缩放为固定宽高100 px。
String style = "image/resize,l_100";
GeneratePresignedUrlRequest req= new GeneratePresignedUrlRequest(bucketName,key);
req.setExpiration(expiration);
req.setProcess(style);
String singdUrl= client.generatePresignedUrl(req).toString();
PageData pd=new PageData();
pd.put("fileUrl",fileUrl);//原图
pd.put("singdUrl",singdUrl);//缩略图
return pd;
}
/**
* 分段上传大文件,通过Multipart的方式上传一个大文件,要上传文件的大小必须大于一个Part允许的最小大小,即5MB。
* @throws OSSException
* @throws ClientException
* @throws InterruptedException
*/
public static String uploadBigFile(MultipartFile file,String filename) throws OSSException, ClientException, InterruptedException {
long begin = System.currentTimeMillis();
ClientConfiguration config = new ClientConfiguration();
config.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
config.setSocketTimeout(15 * 1000);// socket超时,默认15秒
config.setMaxConnections(10); // // 设置HTTP最大连接数为10
config.setMaxErrorRetry(2);// 失败后最大重试次数
OSSClient client = new OSSClient(OSS_ENDPOINT, ACCESS_ID, ACCESS_KEY, config);
// OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret,conf);
//String key = String.format("%s%s.%s",picLocation,UuidUtil.get32UUID(),fileTypeName);
String key = "patient/"+filename;
int partCount = calPartCount(file.getSize());
// System.out.println("partCountpartCountpartCountpartCount"+partCount);
if (partCount <= 1) {
throw new IllegalArgumentException("要上传文件的大小必须大于一个Part的字节数:" + PART_SIZE);
}
String uploadId = initMultipartUpload(client,bucketName, key);
ExecutorService pool = Executors.newFixedThreadPool(CONCURRENCIES);
List<PartETag> eTags = Collections.synchronizedList(new ArrayList<PartETag>());
for (int i = 0; i < partCount; i++) {
long start = PART_SIZE * i;
long curPartSize = PART_SIZE < file.getSize() - start ? PART_SIZE : file.getSize() - start;
pool.execute(new UploadPartThread(client,bucketName, key,file, uploadId, i + 1, PART_SIZE * i, curPartSize,eTags));
}
pool.shutdown();
while (!pool.isTerminated()) {
pool.awaitTermination(5, TimeUnit.SECONDS);
}
if (eTags.size() != partCount) {
throw new IllegalStateException("Multipart上传失败,有Part未上传成功。");
}
completeMultipartUpload(client,bucketName, key, uploadId, eTags);
String fileUrl = "";
long end = System.currentTimeMillis();
// System.out.println(end - begin);
Date expiration = new Date(new Date().getTime() + 3600l*1000*24*365*100);
// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
fileUrl = client.generatePresignedUrl(bucketName, key, expiration).toString().replace("-internal", "");
return fileUrl;
}
/**
* 分段上传大文件获得缩略图,通过Multipart的方式上传一个大文件,要上传文件的大小必须大于一个Part允许的最小大小,即5MB。
* @throws OSSException
* @throws ClientException
* @throws InterruptedException
*/
public static String ossUplodeSingdUrl(MultipartFile file,String filename) throws OSSException, ClientException, InterruptedException {
long begin = System.currentTimeMillis();
ClientConfiguration config = new ClientConfiguration();
config.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
config.setSocketTimeout(15 * 1000);// socket超时,默认15秒
config.setMaxConnections(10); // // 设置HTTP最大连接数为10
config.setMaxErrorRetry(2);// 失败后最大重试次数
OSSClient client = new OSSClient(OSS_ENDPOINT, ACCESS_ID, ACCESS_KEY, config);
// OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret,conf);
//String key = String.format("%s%s.%s",picLocation,UuidUtil.get32UUID(),fileTypeName);
String key = "patient/"+filename;
int partCount = calPartCount(file.getSize());
// System.out.println("partCountpartCountpartCountpartCount"+partCount);
if (partCount <= 1) {
throw new IllegalArgumentException("要上传文件的大小必须大于一个Part的字节数:" + PART_SIZE);
}
String uploadId = initMultipartUpload(client,bucketName, key);
ExecutorService pool = Executors.newFixedThreadPool(CONCURRENCIES);
List<PartETag> eTags = Collections.synchronizedList(new ArrayList<PartETag>());
for (int i = 0; i < partCount; i++) {
long start = PART_SIZE * i;
long curPartSize = PART_SIZE < file.getSize() - start ? PART_SIZE : file.getSize() - start;
pool.execute(new UploadPartThread(client,bucketName, key,file, uploadId, i + 1, PART_SIZE * i, curPartSize,eTags));
}
pool.shutdown();
while (!pool.isTerminated()) {
pool.awaitTermination(5, TimeUnit.SECONDS);
}
if (eTags.size() != partCount) {
throw new IllegalStateException("Multipart上传失败,有Part未上传成功。");
}
completeMultipartUpload(client,bucketName, key, uploadId, eTags);
long end = System.currentTimeMillis();
// System.out.println(end - begin);
Date expiration = new Date(new Date().getTime() + 3600l*1000*24*365*100);
// 将图片缩放为固定宽高100 px。
String style = "image/resize,l_100";
GeneratePresignedUrlRequest req= new GeneratePresignedUrlRequest(bucketName,key);
req.setExpiration(expiration);
req.setProcess(style);
String singdUrl= client.generatePresignedUrl(req).toString();
return singdUrl;
}
// 根据文件的大小和每个Part的大小计算需要划分的Part个数。
private static int calPartCount(long length) {
int partCount = (int) (length / PART_SIZE);
if (length % PART_SIZE != 0) {
partCount++;
}
return partCount;
}
// 初始化一个Multi-part upload请求。
private static String initMultipartUpload(OSSClient client,String bucketName, String key) throws OSSException, ClientException {
InitiateMultipartUploadRequest initUploadRequest = new InitiateMultipartUploadRequest(bucketName, key);
InitiateMultipartUploadResult initResult = client.initiateMultipartUpload(initUploadRequest);
String uploadId = initResult.getUploadId();
return uploadId;
}
// 完成一个multi-part请求。
private static void completeMultipartUpload(OSSClient client,String bucketName, String key, String uploadId, List<PartETag> eTags) throws OSSException, ClientException {
// 为part按partnumber排序
Collections.sort(eTags, new Comparator<PartETag>() {
public int compare(PartETag arg0, PartETag arg1) {
PartETag part1 = arg0;
PartETag part2 = arg1;
return part1.getPartNumber() - part2.getPartNumber();
}
});
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, key, uploadId, eTags);
client.completeMultipartUpload(completeMultipartUploadRequest);
}
private static class UploadPartThread implements Runnable {
private MultipartFile file;
private String bucket;
private String object;
private long start;
private long size;
private List<PartETag> eTags;
private int partId;
private OSSClient client;
private String uploadId;
UploadPartThread(OSSClient client,String bucket, String object,MultipartFile file, String uploadId, int partId, long start,long partSize, List<PartETag> eTags) {
this.file = file;
this.bucket = bucket;
this.object = object;
this.start = start;
this.size = partSize;
this.eTags = eTags;
this.partId = partId;
this.client = client;
this.uploadId = uploadId;
}
@Override
public void run() {
InputStream in = null;
try {
in = file.getInputStream();
in.skip(start);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucket);
uploadPartRequest.setKey(object);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setInputStream(in);
uploadPartRequest.setPartSize(size);
uploadPartRequest.setPartNumber(partId);
UploadPartResult uploadPartResult = client.uploadPart(uploadPartRequest);
eTags.add(uploadPartResult.getPartETag());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null)
try {
in.close();
} catch (Exception e) {
}
}
}
}
}
阿里云OSS大文件上传
最新推荐文章于 2024-09-26 18:18:29 发布