腾讯云COS分片上传

package com.ndsoft.single.web.message;

import com.ndsoft.single.common.base.BaseController;
import com.ndsoft.single.common.utils.DateUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

/**
 * 大文件上传
 */
@Controller
public class BlockUploadController extends BaseController {
    private static final String FILE_PATH_PREFIX = "\\";
    private static final String FILE_PREFIX = "/";

    @RequestMapping("/blockUpload")
    @ResponseBody
    public void blockUpload(@RequestParam("file") MultipartFile file) throws Exception {
        // 文件的完整名字
        String fileName = file.getOriginalFilename();
        if (fileName.contains(FILE_PATH_PREFIX)) {
            fileName = fileName.substring(fileName.lastIndexOf(FILE_PATH_PREFIX) + 1);
        }
        String type = fileName.substring(fileName.lastIndexOf(".") + 1);
        Random rand = new Random();
        int random = rand.nextInt();
        // 上传后的名称
        String key = FILE_PREFIX + DateUtil.getDateStr("yyMMddHHmmss") + (random > 0 ? random : (-1) * random) + "." + type;
        // 获取分块上传的 uploadId
        String uploadId = InitMultipartUploadDemo(key);
        // 获取上传的所有分块信息
        List<PartETag> partETags = UploadPartDemo(uploadId, key, file);
        // 完成分片上传
        completePartDemo(uploadId, partETags, key);
    }

    /**
     * 获取分块上传的 uploadId
     *
     * @param key
     * @return
     */
    public String InitMultipartUploadDemo(String key) {
        // 1 初始化用户身份信息(secretId, secretKey)
        // ndFileProperties.getOssTxcosAccessKey() 指 accessKey; ndFileProperties.getOssTxcosAccessSecret() 指 SecretKey
        COSCredentials cred = new BasicCOSCredentials(ndFileProperties.getOssTxcosAccessKey(), ndFileProperties.getOssTxcosAccessSecret());
        // 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
        // ndFileProperties.getOssTxcosRegion() - 存储桶所在的地域
        ClientConfig clientConfig = new ClientConfig(new Region(ndFileProperties.getOssTxcosRegion()));
        // 3 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        // bucket名需包含appid  ndFileProperties.getOssTxcosDefaultBucketName()-此处填写的存储桶名称必须为此格式
        String bucketName = ndFileProperties.getOssTxcosDefaultBucketName();
        // 初始化分块上传任务
        InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, key);
        // 设置存储类型, 默认是标准(Standard), 低频(Standard_IA), 归档(Archive)
        request.setStorageClass(StorageClass.Standard);
        try {
            InitiateMultipartUploadResult initResult = cosclient.initiateMultipartUpload(request);
            // 获取uploadid
            String uploadId = initResult.getUploadId();
            return uploadId;
        } catch (CosServiceException e) {
            throw e;
        } catch (CosClientException e) {
            throw e;
        } finally {
            cosclient.shutdown();
        }
    }

    /**
     * 获取上传的所有分块信息
     *
     * @param uploadId
     * @param key
     * @param file
     * @return
     * @throws IOException
     */
    public List<PartETag> UploadPartDemo(String uploadId, String key, MultipartFile file) throws IOException {
        // 1 初始化用户身份信息(secretId, secretKey)
        // ndFileProperties.getOssTxcosAccessKey() 指 accessKey; ndFileProperties.getOssTxcosAccessSecret() 指 SecretKey
        COSCredentials cred = new BasicCOSCredentials(ndFileProperties.getOssTxcosAccessKey(), ndFileProperties.getOssTxcosAccessSecret());
        // 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
        // ndFileProperties.getOssTxcosRegion() 指 存储桶所在的地域 如:ap-shanghai
        ClientConfig clientConfig = new ClientConfig(new Region(ndFileProperties.getOssTxcosRegion()));
        // 3 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        // bucket名需包含appid
        String bucketName = ndFileProperties.getOssTxcosDefaultBucketName();
        // 是否进行流量控制
        boolean userTrafficLimit = false;
        // 所有分块
        List<PartETag> partETags = new LinkedList<>();
        // 每片分块的大小
        int partSize = 2 * 1024 * 1024 * 100;
        // 上传文件的大小
        long fileSize = file.getSize();
        // 分块片数
        int partCount = (int) (fileSize / partSize);
        if (fileSize % partSize != 0) {
            partCount++;
        }
        // 生成要上传的数据, 这里初始化一个10M的数据
        for (int i = 0; i < partCount; i++) {
            // 起始位置
            long startPos = i * partSize;
            // 分片大小
            long curPartSize = (i + 1 == partCount) ? (fileSize - startPos) : partSize;
            // 大文件
            InputStream instream = file.getInputStream();
            // 跳过已经上传的分片。
            instream.skip(startPos);
            // 用于上传分块请求
            UploadPartRequest uploadPartRequest = new UploadPartRequest();
            // 存储桶命名
            uploadPartRequest.setBucketName(bucketName);
            // 指定分块上传到 COS 上的路径
            uploadPartRequest.setKey(key);
            // 标识指定分块上传的 uploadId
            uploadPartRequest.setUploadId(uploadId);
            // 设置分块的数据来源输入流
            uploadPartRequest.setInputStream(instream);
            // 设置分块的长度
            uploadPartRequest.setPartSize(curPartSize);
            // 上传分片编号
            uploadPartRequest.setPartNumber(i + 1);
            // 是否进行流量控制
            if (userTrafficLimit) {
                // 用于对上传对象进行流量控制,单位:bit/s,默认不进行流量控制
                uploadPartRequest.setTrafficLimit(8 * 1024 * 1024);
            }
            try {
                // 上传分片数据的输入流
                UploadPartResult uploadPartResult = cosclient.uploadPart(uploadPartRequest);
                // 获取上传分块信息
                PartETag partETag = uploadPartResult.getPartETag();
                // 把上传返回的分块信息放入到分片集合中
                partETags.add(partETag);
                // 获取复制生成对象的CRC64
                String crc64 = uploadPartResult.getCrc64Ecma();
            } catch (CosServiceException e) {
                throw e;
            } catch (CosClientException e) {
                throw e;
            }
        }
        cosclient.shutdown();
        return partETags;
    }

    /**
     * 完成分片上传
     *
     * @param uploadId
     * @param partETags
     * @param key
     */
    public void completePartDemo(String uploadId, List<PartETag> partETags, String key) {
        // 1 初始化用户身份信息(secretId, secretKey)  accessKey-腾讯云cos accessKey, secretKey-腾讯云cos 访问Secret
        // ndFileProperties.getOssTxcosAccessKey() 指 accessKey; ndFileProperties.getOssTxcosAccessSecret() 指 SecretKey
        COSCredentials cred = new BasicCOSCredentials(ndFileProperties.getOssTxcosAccessKey(), ndFileProperties.getOssTxcosAccessSecret());
        // 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
        ClientConfig clientConfig = new ClientConfig(new Region(ndFileProperties.getOssTxcosRegion()));
        // 3 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        // bucket名需包含appid
        String bucketName = ndFileProperties.getOssTxcosDefaultBucketName();
        // 分片上传结束后,调用complete完成分片上传
        CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, key, uploadId, partETags);
        try {
            CompleteMultipartUploadResult completeResult = cosclient.completeMultipartUpload(completeMultipartUploadRequest);
            String etag = completeResult.getETag();
            String crc64 = completeResult.getCrc64Ecma();
        } catch (CosServiceException e) {
            throw e;
        } catch (CosClientException e) {
            throw e;
        }
        cosclient.shutdown();
    }

}

 Maven

<dependency>
    <groupId>com.qcloud</groupId>
    <artifactId>cos_api</artifactId>
    <version>5.6.22</version>
</dependency>                

 Postman请求

posted @ 2021-09-08 16:51  蛋挞小子  阅读(1587)  评论(0编辑  收藏  举报