阿里云oss分片上传,删除

转载请表明出处 https://blog.csdn.net/Amor_Leo/article/details/106843750 谢谢

阿里云oss分片上传,删除

  • pom
  • yml
  • 工具类

pom

<!--        oss 阿里储存-->
        
            com.aliyun.oss
            aliyun-sdk-oss
            3.8.1
        

yml

# OSS相关配置信息
aliyun:
  oss:
    endpoint: xxxx # oss对外服务的访问域名
    accessKeyId: xxxx # 访问身份验证中用到用户标识
    accessKeySecret: xxxx # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
    bucketName: xxxx# oss的存储空间
    baseFile: zzz/ #指定上传文件夹
    urlPrefix: http://oss的存储空间.oss对外服务的访问域名/

工具类

oss分片上传

/**
 * 阿里OSS对象存储文件上传工具类
 *
 * @author LHL
 */
@Slf4j
@Component
public class FileUploadOssUtil {

	private static String endpoint;
	private static String accessKeyId;
	private static String accessKeySecret;
	private static String bucketName;
	private static String baseFile;
	private static String urlPrefix;

	@Value("${aliyun.oss.endpoint}")
	public void setEndpoint(String endpoint) {
		this.endpoint = endpoint;
	}

	@Value("${aliyun.oss.accessKeyId}")
	public void setAccessKeyId(String accessKeyId) {
		this.accessKeyId = accessKeyId;
	}

	@Value("${aliyun.oss.accessKeySecret}")
	public void setAccessKeySecret(String accessKeySecret) {
		this.accessKeySecret = accessKeySecret;
	}

	@Value("${aliyun.oss.bucketName}")
	public void setBucketName(String bucketName) {
		this.bucketName = bucketName;
	}

	@Value("${aliyun.oss.baseFile}")
	public void setBaseFile(String baseFile) {
		this.baseFile = baseFile;
	}

	@Value("${aliyun.oss.urlPrefix}")
	public void setUrlPrefix(String urlPrefix) {
		this.urlPrefix = urlPrefix;
	}

	private static String key = null;

	private static OSS client = null;

	/**
	 * 定长线程池
	 */
	private static ExecutorService threadPool;


	private static List<PartETag> partETags = null;

	/**
	 * 2MB 分片大小
	 */
	private static final int partSize = 2 * 1024 * 1024;

	private static int counter = 0;

	/**
	 * 删除文件
	 */
	public static boolean remove(String filePath) {
		String path = filePath.replaceAll(urlPrefix, "");
		try {
			client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
			client.deleteObject(bucketName, path);
			log.info("oss删除成功 路径: {}", filePath);
		} catch (OSSException e) {
			log.error(e.getMessage(), e);
			return false;
		} finally {
			if (client != null) {
				client.shutdown();
			}
		}
		return true;
	}
	
	/*
	* 上传oss
	* @author LHL
	*/
	private static String upload(MultipartFile multipartFile, String baseDir) throws IOException {
		String fileName = multipartFile.getOriginalFilename();
		long start = System.currentTimeMillis();
		String[] names = fileName.split("\\.");
		String fileTypeName = names[names.length - 1];
		key = baseDir + "/" + UUID.randomUUID().toString().replaceAll("-", "") + "." + fileTypeName;
		client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
		String fileUrl = null;
		try {
			String uploadId = claimUploadId(key);
			log.info("申请一个新的上传id:" + uploadId);
			// 文件大小
			long fileLength = multipartFile.getSize();
			// 分片总数(总共分几个部分)
			int partCount = (int) (fileLength / partSize);
			if (fileLength % partSize != 0) {
				partCount++;
			}
			if (partCount > 10000) {
				log.warn("partCount总数不应超过10000");
				return null;
			} else {
				log.info("文件总共分片数:" + partCount);
			}
			partETags = Collections.synchronizedList(new ArrayList<PartETag>(partCount));
			CountDownLatch latch = new CountDownLatch(partCount);
			log.info("***************开始准备上传************");
			threadPool = ThreadConstants.getMyThreadPool();
			for (int i = 0; i < partCount; i++) {
				long startPos = i * partSize;
				long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
				threadPool.execute(new PartUploader(multipartFile, startPos, curPartSize, i + 1, uploadId, latch));
			}
			latch.await();
			if (partETags.size() != partCount) {
				StringBuilder partETagsStr = new StringBuilder("(");
				for (PartETag item : partETags) {
					partETagsStr.append(item.getPartNumber()).append(",");
				}
				partETagsStr.append(")");
				log.info(String.format("partCount:%s*******,partEtages:%s*******,partETagsSize:%s", partCount, partETagsStr, partETags.size()));
				throw new IllegalStateException("上传多个部分失败,因为有些部分还没有完成");
			} else {
				log.info("成功地将多个部分合并上传到一个名为的对象中 " + key);
			}
			listAllParts(uploadId);
			completeMultipartUpload(uploadId);
			log.info("获取一个对象");
			long end = System.currentTimeMillis();
			// 生成文件地址
			boolean isFileExist = client.doesObjectExist(bucketName, key);
			if (isFileExist) {
				fileUrl = urlPrefix + key;
				log.info(String.format("上传成功*****耗时:%s*****,文件地址:%s", ((end - start) / 1000), fileUrl));
			} else {
				throw new Exception("上传失败,文件不存在");
			}
		} catch (OSSException oe) {
			log.error(oe.getMessage(), oe);
		} catch (ClientException ce) {
			log.error(ce.getErrorMessage(), ce);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			if (client != null) {
				client.shutdown();
			}
			partETags.clear();
			partETags = null;

		}
		return fileUrl;
	}


	/**
	 * 静态内部类,上传组件
	 */
	private static class PartUploader implements Runnable {
		private MultipartFile localFile;
		private long partSize;
		private int partNumber;
		private String uploadId;
		private long startPos;
		private CountDownLatch latch;

		public PartUploader(MultipartFile localFile, long startPos, long partSize, int partNumber, String uploadId, CountDownLatch latch) {
			this.localFile = localFile;
			this.partSize = partSize;
			this.partNumber = partNumber;
			this.uploadId = uploadId;
			this.startPos = startPos;
			this.latch = latch;
		}

		@Override
		public void run() {
			InputStream instream = null;
			try {
				log.info("Part#" + this.partNumber + " 开始上传\n");
				instream = localFile.getInputStream();
				instream.skip(startPos);
				UploadPartRequest uploadPartRequest = new UploadPartRequest();
				uploadPartRequest.setBucketName(bucketName);
				uploadPartRequest.setKey(key);
				uploadPartRequest.setUploadId(this.uploadId);
				uploadPartRequest.setInputStream(instream);
				uploadPartRequest.setPartSize(this.partSize);
				uploadPartRequest.setPartNumber(this.partNumber);
				UploadPartResult uploadPartResult = client.uploadPart(uploadPartRequest);
				log.info("Part#" + this.partNumber + " 完毕\n");
				synchronized (partETags) {
					partETags.add(uploadPartResult.getPartETag());
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (instream != null) {
					try {
						instream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				latch.countDown();
			}
		}
	}

	private static String claimUploadId(String path) {
		InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, key);
		// 大家可根据自己的文件类型,设置不同的响应content-type
		String contentType = getContentType(path);
		if (StringUtils.isNotBlank(contentType)) {
			request.addHeader("Content-Type", contentType);
		}
		request.addHeader("Cache-Control", "no-cache");
		InitiateMultipartUploadResult result = client.initiateMultipartUpload(request);
		return result.getUploadId();
	}

     //有些不常用的可能有问题 
	private static String getContentType(String inputPath) {
		String type = inputPath.substring(inputPath.lastIndexOf(".") + 1).toLowerCase();
		// 判断是否为音频 mp3、aac、ape/flac、wav、wma、amr、mid
		if (type.equalsIgnoreCase("mp3")) {
			return "audio/mpeg";
		} else if (type.equalsIgnoreCase("aac")) {
			return "audio/mpeg";
		} else if (type.equalsIgnoreCase("ape")) {
			return "audio/mpeg";
		} else if (type.equalsIgnoreCase("wav")) {
			return "audio/mpeg";
		} else if (type.equalsIgnoreCase("wma")) {
			return "audio/mpeg";
		} else if (type.equalsIgnoreCase("amr")) {
			return "audio/AMR";
		} else if (type.equalsIgnoreCase("mid")) {
			return "audio/mpeg";
		}
		//判断是否为图片 jpg、png、gif、bmp、ico、tif(tiff)、psd/psb、WebP、RAW、pdf、DCM、sai/rif
		else if (type.equalsIgnoreCase("jpg")) {
			return "image/jpg";
		} else if (type.equalsIgnoreCase("jpeg")) {
			return "image/jpg";
		} else if (type.equalsIgnoreCase("png")) {
			return "image/jpg";
		} else if (type.equalsIgnoreCase("gif")) {
			return "image/gif";
		} else if (type.equalsIgnoreCase("tif")) {
			return "image/tiff";
		} else if (type.equalsIgnoreCase("tiff")) {
			return "image/tiff";
		} else if (type.equalsIgnoreCase("bmp")) {
			return "image/bmp";
		} else if (type.equalsIgnoreCase("pdf")) {
			return "application/pdf";
		} else if (type.equalsIgnoreCase("psd")) {
			return "application/vnd.ms-xpsdocument";
		} else if (type.equalsIgnoreCase("psb")) {
			return "image/jpeg";
		}
		//判断是否为视频 mp4/m4v/3gp/mpg、flv/f4v/swf、avi、wmv、rmvb、mov、mts/m2t、webm/ogg/mkv
		else if (type.equalsIgnoreCase("mp4")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("avi")) {
			return "video/avi";
		} else if (type.equalsIgnoreCase("mov")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("flv")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("wmv")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("asf")) {
			return "allpication/vnd.ms-asf";
		} else if (type.equalsIgnoreCase("asx")) {
			return "allpication/vnd.ms-asf";
		} else if (type.equalsIgnoreCase("wmv9")) {
			return "video/x-ms-wmv";
		} else if (type.equalsIgnoreCase("3gp")) {
			return "audio/3gpp";
		} else if (type.equalsIgnoreCase("mpg")) {
			return "video/mpeg";
		} else if (type.equalsIgnoreCase("rm")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("rmvb")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("mts")) {
			return "model/vnd.mts";
		} else if (type.equalsIgnoreCase("m2t")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("ogg")) {
			return "application/ogg";
		} else if (type.equalsIgnoreCase("m4v")) {
			return "video/mp4";
			} else if (type.equalsIgnoreCase("mkv")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("f4v")) {
			return "video/mp4";
		} else if (type.equalsIgnoreCase("swf")) {
			return "video/vnd.sealed.swf";
		} else if (type.equalsIgnoreCase("webm")) {
			return "video/mp4";
		}
		return null;
	}


	private static void completeMultipartUpload(String uploadId) {
		// Make part numbers in ascending order
		Collections.sort(partETags, new Comparator<PartETag>() {

			@Override
			public int compare(PartETag p1, PartETag p2) {
				return p1.getPartNumber() - p2.getPartNumber();
			}
		});

		log.info("Completing to upload multiparts\n");
		CompleteMultipartUploadRequest completeMultipartUploadRequest =
			new CompleteMultipartUploadRequest(bucketName, key, uploadId, partETags);
		client.completeMultipartUpload(completeMultipartUploadRequest);
	}

	private static void listAllParts(String uploadId) {
		log.info("Listing all parts......");
		ListPartsRequest listPartsRequest = new ListPartsRequest(bucketName, key, uploadId);
		PartListing partListing = client.listParts(listPartsRequest);

		int partCount = partListing.getParts().size();
		for (int i = 0; i < partCount; i++) {
			PartSummary partSummary = partListing.getParts().get(i);
			log.info("\tPart#" + partSummary.getPartNumber() + ", ETag=" + partSummary.getETag());
		}
	}


	/**
	 * 上传执行器
	 */
	public synchronized static String fileUpload(MultipartFile multipartFile) {
		ReentrantLock lock = new ReentrantLock();
		lock.lock();
		long start = System.currentTimeMillis();
		String fileName = multipartFile.getOriginalFilename();
		String baseDir = checkContentType(fileName);
		try {
			baseDir = baseFile + baseDir + "/" + DateUtil.parseDateToStr("yyyyMM", new Date());
			String fileUrl = upload(multipartFile, baseDir);
			long end = System.currentTimeMillis();
			log.info("文件上传结束,共耗时" + (end - start) + "ms");
			return fileUrl;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			lock.unlock();
		}
	}

	private static final File getAbsoluteFile(String filename) throws IOException {
		File desc = new File(File.separator + filename);

		if (!desc.getParentFile().exists()) {
			desc.getParentFile().mkdirs();
		}
		if (!desc.exists()) {
			desc.createNewFile();
		}
		return desc;
	}

	private static final String encodingFilename(String filename, String extension) {
		filename = filename.replace("_", " ");
		filename = MD5Util.md5Encrypt32Lower(filename + System.nanoTime() + counter++) + extension;
		return filename;
	}


	public static String checkContentType(String inputPath) {
		String type = inputPath.substring(inputPath.lastIndexOf(".") + 1).toLowerCase();
		// 判断是否为音频 mp3、aac、ape/flac、wav、wma、amr、mid
		if (type.equalsIgnoreCase("mp3")) {
			return "audio";
		} else if (type.equalsIgnoreCase("aac")) {
			return "audio";
		} else if (type.equalsIgnoreCase("ape")) {
			return "audio";
		} else if (type.equalsIgnoreCase("wav")) {
			return "audio";
		} else if (type.equalsIgnoreCase("wma")) {
			return "audio";
		} else if (type.equalsIgnoreCase("amr")) {
			return "audio";
		} else if (type.equalsIgnoreCase("mid")) {
			return "audio";
		}
		//判断是否为图片 jpg、png、gif、bmp、ico、tif(tiff)、psd/psb、WebP、RAW、pdf、DCM、sai/rif
		else if (type.equalsIgnoreCase("jpg")) {
			return "picture";
		} else if (type.equalsIgnoreCase("jpeg")) {
			return "picture";
		} else if (type.equalsIgnoreCase("png")) {
			return "picture";
		} else if (type.equalsIgnoreCase("gif")) {
			return "picture";
		} else if (type.equalsIgnoreCase("tif")) {
			return "picture";
		} else if (type.equalsIgnoreCase("tiff")) {
			return "picture";
		} else if (type.equalsIgnoreCase("bmp")) {
			return "picture";
		} else if (type.equalsIgnoreCase("pdf")) {
			return "picture";
		} else if (type.equalsIgnoreCase("psd")) {
			return "picture";
		} else if (type.equalsIgnoreCase("psb")) {
			return "picture";
		}
		//判断是否为视频 mp4/m4v/3gp/mpg、flv/f4v/swf、avi、wmv、rmvb、mov、mts/m2t、webm/ogg/mkv
		else if (type.equalsIgnoreCase("mp4")) {
			return "video";
		} else if (type.equalsIgnoreCase("avi")) {
			return "video";
		} else if (type.equalsIgnoreCase("mov")) {
			return "video";
		} else if (type.equalsIgnoreCase("flv")) {
			return "video";
		} else if (type.equalsIgnoreCase("wmv")) {
			return "video";
		} else if (type.equalsIgnoreCase("asf")) {
			return "video";
		} else if (type.equalsIgnoreCase("asx")) {
			return "video";
		} else if (type.equalsIgnoreCase("wmv9")) {
			return "video";
		} else if (type.equalsIgnoreCase("3gp")) {
			return "video";
		} else if (type.equalsIgnoreCase("mpg")) {
			return "video";
		} else if (type.equalsIgnoreCase("rm")) {
			return "video";
		} else if (type.equalsIgnoreCase("rmvb")) {
			return "video";
		} else if (type.equalsIgnoreCase("mts")) {
			return "video";
		} else if (type.equalsIgnoreCase("m2t")) {
			return "video";
		} else if (type.equalsIgnoreCase("ogg")) {
			return "video";
		} else if (type.equalsIgnoreCase("m4v")) {
			return "video";
		} else if (type.equalsIgnoreCase("mkv")) {
			return "video";
		} else if (type.equalsIgnoreCase("f4v")) {
			return "video";
		} else if (type.equalsIgnoreCase("swf")) {
			return "video";
		} else if (type.equalsIgnoreCase("webm")) {
			return "video";
		}
		return "other";
	}
}


/**
 * 获取静态单例固定线程池
 *
 * @author LHL
 */
public class ThreadConstants {


	public static final int MAX_THREAD_COUNT = 10;

	/**
	 * 自定义线程池
	 */
	private static ExecutorService MY_THREAD_POOL;

	/**
	 * 自定义线程池
	 */
	public static ExecutorService getMyThreadPool() {
		if (MY_THREAD_POOL == null) {
			MY_THREAD_POOL = Executors.newFixedThreadPool(MAX_THREAD_COUNT);
		}
		return MY_THREAD_POOL;
	}
}

你可能感兴趣的:(JAVA,java,oss)