4848import java .util .concurrent .Future ;
4949import java .util .concurrent .TimeUnit ;
5050
51+ import com .aliyun .oss .event .ProgressEventType ;
52+ import com .aliyun .oss .event .ProgressListener ;
53+ import com .aliyun .oss .event .ProgressPublisher ;
5154import com .aliyun .oss .model .DownloadFileRequest ;
5255import com .aliyun .oss .model .DownloadFileResult ;
5356import com .aliyun .oss .model .GenericRequest ;
@@ -335,14 +338,22 @@ private DownloadFileResult downloadFileWithCheckpoint(DownloadFileRequest downlo
335338 prepare (downloadCheckPoint , downloadFileRequest );
336339 }
337340
341+ // 进度条开始下载数据
342+ ProgressListener listener = downloadFileRequest .getProgressListener ();
343+ ProgressPublisher .publishProgress (listener , ProgressEventType .TRANSFER_STARTED_EVENT );
344+
338345 // 并发下载分片
339346 DownloadResult downloadResult = download (downloadCheckPoint , downloadFileRequest );
340347 for (PartResult partResult : downloadResult .getPartResults ()) {
341348 if (partResult .isFailed ()) {
349+ ProgressPublisher .publishProgress (listener , ProgressEventType .TRANSFER_PART_FAILED_EVENT );
342350 throw partResult .getException ();
343351 }
344352 }
345353
354+ // 进度条下载数据完成
355+ ProgressPublisher .publishProgress (listener , ProgressEventType .TRANSFER_COMPLETED_EVENT );
356+
346357 // 重命名临时文件
347358 renameTo (downloadFileRequest .getTempDownloadFile (), downloadFileRequest .getDownloadFile ());
348359
@@ -389,10 +400,23 @@ private DownloadResult download(DownloadCheckPoint downloadCheckPoint, DownloadF
389400 ExecutorService service = Executors .newFixedThreadPool (downloadFileRequest .getTaskNum ());
390401 ArrayList <Future <PartResult >> futures = new ArrayList <Future <PartResult >>();
391402 List <Task > tasks = new ArrayList <Task >();
392-
403+ ProgressListener listener = downloadFileRequest .getProgressListener ();
404+
405+ // 计算待下载的数据量
406+ long contentLength = 0 ;
407+ for (int i = 0 ; i < downloadCheckPoint .downloadParts .size (); i ++) {
408+ if (!downloadCheckPoint .downloadParts .get (i ).isCompleted ) {
409+ long partSize = downloadCheckPoint .downloadParts .get (i ).end - downloadCheckPoint .downloadParts .get (i ).start + 1 ;
410+ contentLength += partSize ;
411+ }
412+ }
413+ ProgressPublisher .publishResponseContentLength (listener , contentLength );
414+ downloadFileRequest .setProgressListener (null );
415+
416+ // 下载数据分片
393417 for (int i = 0 ; i < downloadCheckPoint .downloadParts .size (); i ++) {
394418 if (!downloadCheckPoint .downloadParts .get (i ).isCompleted ) {
395- Task task = new Task (i , "download-" + i , downloadCheckPoint , i , downloadFileRequest , objectOperation );
419+ Task task = new Task (i , "download-" + i , downloadCheckPoint , i , downloadFileRequest , objectOperation , listener );
396420 futures .add (service .submit (task ));
397421 tasks .add (task );
398422 } else {
@@ -402,42 +426,48 @@ private DownloadResult download(DownloadCheckPoint downloadCheckPoint, DownloadF
402426 }
403427 service .shutdown ();
404428
429+ // 等待分片下载完成
405430 service .awaitTermination (Long .MAX_VALUE , TimeUnit .SECONDS );
406-
407431 for (Future <PartResult > future : futures ) {
408432 try {
409433 PartResult tr = future .get ();
410434 taskResults .add (tr );
411435 } catch (ExecutionException e ) {
436+ downloadFileRequest .setProgressListener (listener );
412437 throw e .getCause ();
413438 }
414439 }
415440
441+ // 对PartResult按照分片序号排序
416442 Collections .sort (taskResults , new Comparator <PartResult >() {
417443 @ Override
418444 public int compare (PartResult p1 , PartResult p2 ) {
419445 return p1 .getNumber () - p2 .getNumber ();
420446 }
421447 });
422448
449+ // 设置返回结果
423450 downloadResult .setPartResults (taskResults );
424451 if (tasks .size () > 0 ) {
425452 downloadResult .setObjectMetadata (tasks .get (0 ).GetobjectMetadata ());
426453 }
454+ downloadFileRequest .setProgressListener (listener );
427455
428456 return downloadResult ;
429457 }
430458
431459 static class Task implements Callable <PartResult > {
432460
433461 public Task (int id , String name , DownloadCheckPoint downloadCheckPoint , int partIndex ,
434- DownloadFileRequest downloadFileRequest , OSSObjectOperation objectOperation ) {
462+ DownloadFileRequest downloadFileRequest , OSSObjectOperation objectOperation ,
463+ ProgressListener progressListener ) {
435464 this .id = id ;
436465 this .name = name ;
437466 this .downloadCheckPoint = downloadCheckPoint ;
438467 this .partIndex = partIndex ;
439468 this .downloadFileRequest = downloadFileRequest ;
440469 this .objectOperation = objectOperation ;
470+ this .progressListener = progressListener ;
441471 }
442472
443473 @ Override
@@ -476,6 +506,8 @@ public PartResult call() throws Exception {
476506 if (downloadFileRequest .isEnableCheckpoint ()) {
477507 downloadCheckPoint .dump (downloadFileRequest .getCheckpointFile ());
478508 }
509+ ProgressPublisher .publishResponseBytesTransferred (progressListener ,
510+ (downloadPart .end - downloadPart .start + 1 ));
479511 } catch (Exception e ) {
480512 tr .setFailed (true );
481513 tr .setException (e );
@@ -504,6 +536,7 @@ public ObjectMetadata GetobjectMetadata () {
504536 private DownloadFileRequest downloadFileRequest ;
505537 private OSSObjectOperation objectOperation ;
506538 private ObjectMetadata objectMetadata ;
539+ private ProgressListener progressListener ;
507540 }
508541
509542 private ArrayList <DownloadPart > splitFile (long objectSize , long partSize ) {
0 commit comments