废话不多说,把代码贴出来。

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();}}}
}

阿里云OSS 分块上传的代码整理相关推荐

  1. SpringBoot整合阿里云OSS文件上传、下载、查看、删除

    SpringBoot整合阿里云OSS文件上传.下载.查看.删除 该项目源码地址:https://github.com/ggb2312/springboot-integration-examples ( ...

  2. 阿里云oss文件上传工具类

    阿里云oss文件上传工具类 阿里云oss 阿里云oss 导入文件阿里云oss的maven依赖 <!-- 阿里云oss依赖 --><dependency><groupId& ...

  3. Java中阿里云OSS文件上传工具类

    阿里云OSS文件上传下载工具类 前言: 本质上就是获取配置文件信息,然后注入bean,调用sdk中提供的增删改方法: 为了避免同名文件会替换,用了hutool中唯一id生成+文件名做拼接 导入依赖:→ ...

  4. 阿里云 OSS监控上传进度

    阿里云 OSS监控上传进度 阿里云上传进度SDK 使用阿里云带进度条的上传,然后将长传进度存入session // 带进度条的上传ossClient.putObject(new PutObjectRe ...

  5. 解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题

    解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题 问题描述 java程序,使用阿里云oss文件上传服务,在测试时偶然发现,我用苹果手机开启高清进行摄像,将原图通过qq传到电脑上,在电 ...

  6. 阿里云oss视频上传后,如何获取视频封面

    前言:在阿里云oss视频上传后,我们如何获取视频封面呢?而不是通过上传方式获取封面.其实OSS本身提供了视频截帧功能 OSS提供的视频截帧功能和OSS图片服务功能使用的方式是类似的,都是通过传入x-o ...

  7. 阿里云OSS文件上传下载,拿来即用

    什么是OSS 我们可以理解为就是一个资源服务器,在这之前我也尝试过Nginx当静态资源服务器,但效果比较一般,为什么选择阿里云OSS,只是因为最近刚好公司用到了,所以就接入了,还有其他的比如七牛云,腾 ...

  8. C#阿里云oss接口上传和下载文件

    一  前期准备工作:需要获取阿里云的:endpoint, accessKeyId, accessKeySecret这三个参数值,可以登录阿里云账号获取到. 再一个就是项目中需要引入阿里云的接口文件Al ...

  9. springboot+阿里云OSS分片上传、断点续传、秒传

    最近工作中有使用到OSS的分片上传API,整体流程就是前端将大文件进行分割,每个分片大小是1MB,分片个数是:(文件总大小 / 单个分片大小),前端多线程处理上传分片到后端,后端接收到分片后调用OSS ...

最新文章

  1. 未能加载文件或程序集“*****.dll”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。(异常来自HRESULT:0x80131040)
  2. 职高学会计电算化好还是学计算机好,会计电算化主要学什么?
  3. 设置edittext不自动获取焦点
  4. Redis作者摊上事了:多人要求修改Redis主从复制术语master/slave
  5. flowjo软件使用方法_管家婆软件使用方法出库教程,管家婆软件做账流程视频_双全科技...
  6. FF:纳斯达克要求退市系误读 警示函仅与推迟提交Q3财报相关
  7. java 抽象类和接口1--基本概念
  8. error C2065: “LOAD_LIBRARY_SEARCH_SYSTEM32”: 未声明的标识符
  9. 信息图表是如何炼成的之一:媒体使用情况
  10. 【机器人算法】机器人运动学参数辨识/DH参数校准/DH参数辨识
  11. 《SEM长尾搜索营销策略解密》一一1.3 别只守着核心词,还有更多风景
  12. 数据结构分类及八种常见数据结构
  13. 块数据3.0:秩序互联网与主权区块链
  14. 修改linux系统的时间EDT和EST为CST
  15. 使用 SkyEye 模拟 ARM Linux
  16. iOS开发特殊日期灰色界面的实现
  17. linux系统中串口驱动的基本实现原理
  18. Premiere视频片段剪辑、添加音乐、添加字幕
  19. 超声波测距仪编程_Micropython教程之TPYBoard DIY超声波测距仪实例演示
  20. mysql 判断时间是否当天_mysql判断时间是否是当天,昨天。。。

热门文章

  1. python测试开发教程_python3测试工具开发快速入门教程
  2. 计算机 和金融主要学什么,计算机和金融哪个更好?未来发展有什么区别?
  3. 云收藏系统|基于Springboot实现云收藏系统
  4. 读书寄语:慎独自律,学思并重
  5. Vue之MVVM、Vue实例对象、生命周期
  6. 基于谷歌最新网络模型EfficientNet,使用迁移学习对猫狗图像识别分类的实际案例应用
  7. 可观测性-Metrics-Kafka监控
  8. thegraph部署子图到私有节点macos
  9. matlab sym 画图,poly2sym之后的画图问题
  10. 【BATJ面试必会】JAVA面试到底需要掌握什么?【下】