阿里云OSS 分块上传的代码整理
来源:互联网 发布:法兰克加工中心编程 编辑:程序博客网 时间:2024/05/16 14:25
废话不多说,把代码贴出来。
package com.changba.erp.utils;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.multipart.MultipartFile;import com.aliyun.oss.OSSClient;import com.aliyun.oss.model.CompleteMultipartUploadRequest;import com.aliyun.oss.model.InitiateMultipartUploadRequest;import com.aliyun.oss.model.InitiateMultipartUploadResult;import com.aliyun.oss.model.ListPartsRequest;import com.aliyun.oss.model.PartETag;import com.aliyun.oss.model.PartListing;import com.aliyun.oss.model.PartSummary;import com.aliyun.oss.model.UploadPartRequest;import com.aliyun.oss.model.UploadPartResult;public class AliyunOSSUpload implements Runnable {private MultipartFile localFile;private long startPos;private long partSize;private int partNumber;private String uploadId;private static String key;private static String bucketName;// 新建一个List保存每个分块上传后的ETag和PartNumberprotected static List<PartETag> partETags = Collections.synchronizedList(new ArrayList<PartETag>());private static Logger logger = LoggerFactory.getLogger(FileUploader.class);protected static OSSClient client = null;/** * 创建构造方法 * * @param localFile * 要上传的文件 * @param startPos * 每个文件块的开始 * @param partSize * @param partNumber * @param uploadId * 作为块的标识 * @param key * 上传到OSS后的文件名 */public AliyunOSSUpload(MultipartFile localFile, long startPos, long partSize, int partNumber, String uploadId, String key , String bucketName) {this.localFile = localFile;this.startPos = startPos;this.partSize = partSize;this.partNumber = partNumber;this.uploadId = uploadId;AliyunOSSUpload.key = key;AliyunOSSUpload.bucketName = bucketName;}/** * 分块上传核心方法(将文件分成按照每个5M分成N个块,并加入到一个list集合中) */@Overridepublic void run() {InputStream instream = null;try {// 获取文件流instream = localFile.getInputStream();// 跳到每个分块的开头instream.skip(this.startPos);// 创建UploadPartRequest,上传分块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 = FileUploader.client.uploadPart(uploadPartRequest);logger.info("Part#" + this.partNumber + " done\n");synchronized (partETags) {// 将返回的PartETag保存到List中。partETags.add(uploadPartResult.getPartETag());}} catch (Exception e) {e.printStackTrace();} finally {if (instream != null) {try {// 关闭文件流instream.close();} catch (IOException e) {e.printStackTrace();}}}}/** * 初始化分块上传事件并生成uploadID,用来作为区分分块上传事件的唯一标识 * * @return */protected static String claimUploadId(String bucketName, String key) {InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, key);InitiateMultipartUploadResult result = FileUploader.client.initiateMultipartUpload(request);logger.info(result.getUploadId());return result.getUploadId();}/** * 将文件分块进行升序排序并执行文件上传。 * * @param uploadId */protected static void completeMultipartUpload(String uploadId) {// 将文件分块按照升序排序Collections.sort(partETags, new Comparator<PartETag>() {@Overridepublic int compare(PartETag p1, PartETag p2) {return p1.getPartNumber() - p2.getPartNumber();}});CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName,key, uploadId, partETags);// 完成分块上传FileUploader.client.completeMultipartUpload(completeMultipartUploadRequest);}/** * 列出文件所有分块的清单 * * @param uploadId */protected static void listAllParts(String uploadId) {ListPartsRequest listPartsRequest = new ListPartsRequest(bucketName, key, uploadId);// 获取上传的所有分块信息PartListing partListing = FileUploader.client.listParts(listPartsRequest);// 获取分块的大小int partCount = partListing.getParts().size();// 遍历所有分块for (int i = 0; i < partCount; i++) {PartSummary partSummary = partListing.getParts().get(i);logger.info("分块编号 " + partSummary.getPartNumber() + ", ETag=" + partSummary.getETag());}}}
package com.changba.erp.utils;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.multipart.MultipartFile;import com.aliyun.oss.OSSClient;public class FileUploader {private static String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";private static String accessKeyId = "FAsc5DqUOpCMZqv8";private static String accessKeySecret = "ewbsDctAbvNQbBl4d66mcoYgNC9N9T";private static String bucketName = "mysong";protected static OSSClient client = null;private static Logger logger = LoggerFactory.getLogger(FileUploader.class);public static String fileUpload(MultipartFile file) {// 创建一个可重用固定线程数的线程池。若同一时间线程数大于10,则多余线程会放入队列中依次执行ExecutorService executorService = Executors.newFixedThreadPool(10);String key = file.getOriginalFilename(); // 获取上传文件的名称,作为在OSS上的文件名// 创建OSSClient实例client = new OSSClient(endpoint, accessKeyId, accessKeySecret);try {String uploadId = AliyunOSSUpload.claimUploadId(bucketName, key);// 设置每块为 5M(除最后一个分块以外,其他的分块大小都要大于5MB)final long partSize = 5 * 1024 * 1024L;// 计算分块数目long fileLength = file.getSize();int partCount = (int) (fileLength / partSize);if (fileLength % partSize != 0) {partCount++;}// 分块 号码的范围是1~10000。如果超出这个范围,OSS将返回InvalidArgument的错误码。if (partCount > 10000) {throw new RuntimeException("文件过大(分块大小不能超过10000)");} else {logger.info("一共分了 " + partCount + " 块");}/** * 将分好的文件块加入到list集合中 */for (int i = 0; i < partCount; i++) {long startPos = i * partSize;long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;// 线程执行。将分好的文件块加入到list集合中executorService.execute(new AliyunOSSUpload(file, startPos, curPartSize, i + 1, uploadId, key, bucketName));}/** * 等待所有分片完毕 */// 关闭线程池(线程池不马上关闭),执行以前提交的任务,但不接受新任务。executorService.shutdown();// 如果关闭后所有任务都已完成,则返回 true。while (!executorService.isTerminated()) {try {// 用于等待子线程结束,再继续执行下面的代码executorService.awaitTermination(5, TimeUnit.SECONDS);} catch (InterruptedException e) {e.printStackTrace();}}/** * partETags(上传块的ETag与块编号(PartNumber)的组合) 如果校验与之前计算的分块大小不同,则抛出异常 */System.out.println(AliyunOSSUpload.partETags.size() +" ----- "+partCount);if (AliyunOSSUpload.partETags.size() != partCount) {throw new IllegalStateException("OSS分块大小与文件所计算的分块大小不一致");} else {logger.info("将要上传的文件名 " + key + "\n");}/* * 列出文件所有的分块清单并打印到日志中,该方法仅仅作为输出使用 */AliyunOSSUpload.listAllParts(uploadId);/* * 完成分块上传 */AliyunOSSUpload.completeMultipartUpload(uploadId);// 返回上传文件的URL地址return endpoint + "/" + bucketName + "/" + client.getObject(bucketName, key).getKey();} catch (Exception e) {logger.error("上传失败!", e);return "上传失败!";} finally {AliyunOSSUpload.partETags.clear();if (client != null) {client.shutdown();}}}}
2 0
- 阿里云OSS 分块上传的代码整理
- 阿里云oss post上传文件 JavaScript代码示例 $.ajax()
- 阿里云OSS 上传文件
- 阿里云OSS分片上传
- 阿里云OSS上传thinkphp
- 阿里云OSS 文件上传
- 文件上传结合springmvc至阿里云的oss
- 关于阿里云OSS上传以及下载的处理方法
- 阿里云上传文件,下载文件 oss
- 整合阿里云OSS文件上传1
- 整合阿里云OSS文件上传2
- OSS阿里云文件上传 demo
- Jfinal版阿里云OSS文件上传
- oss 阿里云 javascript 上传图片
- 阿里云OSS上传文件工具类
- android 阿里云OSS文件上传
- java 上传文件到oss(阿里云)
- 阿里云 oss服务器文件上传 java
- [React Error]: Target container is not a DOM element
- HTTP协议笔记
- This application is modifying the autolayout engine from a background thread, which can lead to engi
- Java四种线程池的使用
- tjut 4311
- 阿里云OSS 分块上传的代码整理
- 一份合格产品需求分析文档是这样出来的!
- C#控制台 类作为函数的参数,如何断开实参与形参的关联
- Android APK反编译
- Windows内核的表学习总结
- hdu1241——Oil Deposits(DFS)
- Sticks
- POJ 3667 Hotel
- 数据结构学习笔记(八)字典、及其线性表描述