Oss多線程分片方式上傳文件

public class OssClientFactory {

public static OSSClient createOssClient(String endpoint,
String accessKeyId,
String accessKeySecret,
String bucket) {

  OSSClientBuilder ossClientBuilder=new OSSClientBuilder();
  // 創(chuàng)建OSSClient實(shí)例璧榄。
  OSSClient ossClient = (OSSClient) ossClientBuilder.build(endpoint, accessKeyId, accessKeySecret);
  ossClient.createBucket(bucket);
  return  ossClient;

}
}

package com.jielu.aliyun.oss;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import com.jielu.leetcode.NamedThreadFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

/**

  • OSS Mul-Thread upload file
    */
    public class OssMultipleThreadUploadExecutor {

    private final OSSClient ossClient;

    public OssMultipleThreadUploadExecutor( OSSClient ossClient){
    this.ossClient=ossClient;
    }

    final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
    10,
    50,
    1000 * 60,
    TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<>(),
    new NamedThreadFactory("thread-oss-upload-file"),
    (r, executor) -> r.run()
    );

 public List<PartETag> genPartTag(List<UploadPartRequest> uploadPartResultList) throws InterruptedException {

     CountDownLatch countDownLatch = new CountDownLatch(uploadPartResultList.size());
     List<PartETag> partETags=new ArrayList<>(uploadPartResultList.size());
     for (int i = 1; i < uploadPartResultList.size(); i++) {
         int finalI = i;
         threadPoolExecutor.execute(() -> {
             try {
                 UploadPartResult  uploadPartResult= ossClient.uploadPart(uploadPartResultList.get(finalI));
                 partETags.add(uploadPartResult.getPartETag());
             } catch (Throwable e) {
                 throw new RuntimeException(e);
             }
         });
         countDownLatch.countDown();;
     }
     countDownLatch.await();
     threadPoolExecutor.shutdown();
     Collections.sort(partETags, (o1, o2) -> o1.getPartNumber()-o2.getPartNumber());
     return partETags;

 }

}

package com.jielu.aliyun.oss;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

@Component
public class OssUtil {

/**
 * get the result url this url can be used for download
 * @param multipartFileList
 * @return
 * @throws IOException
 * @throws InterruptedException
 */
public List<String> uploadFileToOss(List<MultipartFile> multipartFileList){
    String endPoint = "", accessKeyId = "", accessKeySecret = "", bucket = "", bucketName = "";
    String objectName = "/lycol/upload/oss/" + FastDateFormat.getInstance("yyyyMMdd", Locale.CHINESE).format(new Date());

    OSSClient ossClient = OssClientFactory.createOssClient(endPoint, accessKeyId, accessKeySecret, bucket);
    InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
    // 初始化分片甘耿。
    InitiateMultipartUploadResult uploadResult = ossClient.initiateMultipartUpload(request);
    String uploadId = uploadResult.getUploadId();
    List<String> res = new ArrayList<>();
    try {

    for (MultipartFile multipartFile : multipartFileList) {

        InputStream inputStream = multipartFile.getInputStream();
        SliceInputStream sliceInputStream = new SliceInputStream(inputStream, 1024);
        List<UploadPartRequest> uploadPartRequestList = sliceInputStream.genUploadPartRequestList(bucketName, objectName, uploadId);
        OssMultipleThreadUploadExecutor ossMultipleThreadUploadExecutor =
                new OssMultipleThreadUploadExecutor(ossClient);

        List<PartETag> partETags = ossMultipleThreadUploadExecutor.genPartTag(uploadPartRequestList);
        CompleteMultipartUploadRequest completeMultipartUploadRequest =
                new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

        CompleteMultipartUploadResult completeMultipartUploadResult =
                ossClient.completeMultipartUpload(completeMultipartUploadRequest);

        res.add(completeMultipartUploadResult.getLocation());
        IOUtils.close(inputStream);
    }
    }

    catch (Exception e){
        throw  new RuntimeException(e);
    }
    finally {
        ossClient.shutdown();
    }

    return res;

}

}

public class SliceInputStream {

private final int partSize;
private InputStream inputStream;


public SliceInputStream(InputStream inputStream,int partSize) {
    this.inputStream = inputStream;
    this.partSize=partSize;
}

public List<UploadPartRequest> genUploadPartRequestList(String bucketName,String objectName,String uploadId
                                                        ) throws IOException {

    final long partSize = this.partSize;
    int fileLength = inputStream.available();
    int partCount = (int) (fileLength / partSize);
    if (fileLength % partSize != 0) {
        partCount++;
    }
    List<UploadPartRequest> uploadPartRequestList = new ArrayList<>();
    for (int i = 0; i < partCount; i++) {
        long startPos = i * partSize;
        long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
        //skip position
        inputStream.skip(startPos);
        UploadPartRequest uploadPartRequest = new UploadPartRequest();
        uploadPartRequest.setBucketName(bucketName);
        uploadPartRequest.setKey(objectName);
        uploadPartRequest.setUploadId(uploadId);
        uploadPartRequest.setInputStream(inputStream);
        uploadPartRequest.setPartSize(curPartSize);
        uploadPartRequestList.add(uploadPartRequest);
    }
    return uploadPartRequestList;

}

public class NamedThreadFactory implements ThreadFactory {

protected static final AtomicInteger POOL_SEQ = new AtomicInteger(1);

protected final AtomicInteger mThreadNum = new AtomicInteger(1);

protected final String mPrefix;

protected final boolean mDaemon;

protected final ThreadGroup mGroup;

public NamedThreadFactory() {
    this("pool-" + POOL_SEQ.getAndIncrement(), false);
}

public NamedThreadFactory(String prefix) {
    this(prefix, false);
}

public NamedThreadFactory(String prefix, boolean daemon) {
    mPrefix = prefix + "-thread-";
    mDaemon = daemon;
    SecurityManager s = System.getSecurityManager();
    mGroup = (s == null) ? Thread.currentThread().getThreadGroup() : s.getThreadGroup();
}

@Override
public Thread newThread(Runnable runnable) {
    String name = mPrefix + mThreadNum.getAndIncrement();
    Thread ret = new Thread(mGroup, runnable, name, 0);
    ret.setDaemon(mDaemon);
    return ret;
}

public ThreadGroup getThreadGroup() {
    return mGroup;
}

詳情請看Git地址:https://github.com/LycolLoveLucy/mixedMutiple

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末儒恋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌男图,老刑警劉巖挠铲,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蟹但,居然都是意外死亡躯泰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門华糖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麦向,“玉大人,你說我怎么就攤上這事缅阳】纳撸” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵十办,是天一觀的道長秀撇。 經(jīng)常有香客問我,道長向族,這世上最難降的妖魔是什么呵燕? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮件相,結(jié)果婚禮上再扭,老公的妹妹穿的比我還像新娘。我一直安慰自己夜矗,他們只是感情好泛范,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著紊撕,像睡著了一般罢荡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天区赵,我揣著相機(jī)與錄音惭缰,去河邊找鬼。 笑死笼才,一個(gè)胖子當(dāng)著我的面吹牛漱受,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骡送,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼昂羡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了各谚?” 一聲冷哼從身側(cè)響起紧憾,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昌渤,沒想到半個(gè)月后赴穗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膀息,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年般眉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片潜支。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甸赃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出冗酿,到底是詐尸還是另有隱情埠对,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布裁替,位于F島的核電站项玛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏弱判。R本人自食惡果不足惜襟沮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昌腰。 院中可真熱鬧开伏,春花似錦、人聲如沸遭商。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劫流。三九已至巫玻,卻和暖如春暑认,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背大审。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留座哩,地道東北人徒扶。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像根穷,于是被迫代替她去往敵國和親姜骡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容