java 实现文件下载进度条

计算不同用户的下载进度

import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;

public class ProgressBarThread implements Runnable {

    private ArrayList<Integer> proList = new ArrayList<Integer>();
    private int progress;//当前进度
    private int totalSize;//下载文法总大小
    private boolean run = true;
    private int showProgress;
    public static HashMap<String, Integer> progressMap = new HashMap<>();//各用户的下载进度
    public static HashMap<String, Boolean> executeStatusMap = new HashMap<>();//各用户是否下载中
    private Long fileId;
    private String token;

    public ProgressBarThread(int totalSize, Long fileId, String token) {
        this.totalSize = totalSize;
        this.fileId = fileId;
        this.token = token;
        //创建进度条时,将指定用户的执行状态改为true
        executeStatusMap.put(token, true);
    }

    /**
     * @param progress 进度
     */
    public void updateProgress(int progress) {
        synchronized (this.proList) {
            if (this.run) {
                this.proList.add(progress);
                this.proList.notify();
            }
        }
    }

    public void finish() {
        this.run = false;
        //关闭进度条
    }

    @Override
    public void run() {
        synchronized (this.proList) {
            try {
                while (this.run) {
                    if (this.proList.size() == 0) {
                        this.proList.wait();
                    }
                    synchronized (proList) {
                        this.progress += this.proList.remove(0);
                        //更新进度条
                        showProgress = (int) ((new BigDecimal((float) this.progress / this.totalSize).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()) * 100);
                        progressMap.put(token + fileId, showProgress);
                        if (showProgress == 100) {
                            //进度100%时将用户的执行状态改为false
                            executeStatusMap.put(token, false);
                        }
                        System.err.println("当前进度:"+showProgress+"%");
                    }
                }
                System.err.println("下载完成");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {
            File file = new File("C:/Users/mfy/Desktop/蜜雪冰城.pdf");
            FileInputStream fis = new FileInputStream(file);
            FileOutputStream fos = new FileOutputStream("D:/nms/img/蜜雪冰城.pdf");
            ProgressBarThread pbt = new ProgressBarThread((int) file.length(), 1L, "000001");//创建进度条
            new Thread(pbt).start();//开启线程,刷新进度条
            byte[] buf = new byte[1024];
            int size = 0;
            while ((size = fis.read(buf)) > -1) {//循环读取
                fos.write(buf, 0, size);
                pbt.updateProgress(size);//写完一次,更新进度条
            }
            pbt.finish();//文件读取完成,关闭进度条
            fos.flush();
            fos.close();
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

获取获取下载进度,可以通过webSocket推送,也可以前端定时调用

    public HzRestResult getProgress(String fileId, HttpServletRequest request) {
        String token = request.getHeader("token");
        Integer progress = ProgressBarThread.progressMap.get(token + fileId);
        if (progress == null) {
            return HzRestResult.getFailed("该任务不存在!");
        }
         if(progress.equals(100)){
            //进度100%时清除指定map
            ProgressBarThread.progressMap.remove(token + fileId);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("fileId", fileId);
        jsonObject.put("token", token);
        jsonObject.put("progress", progress);
        return HzRestResult.getSuccess(jsonObject);
    }
  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用阿里云的Java SDK来实现OSS文件下载,并且通过多线程和进度条来显示下载进度。以下是一个示例代码: ``` import com.aliyun.oss.OSS; import com.aliyun.oss.event.ProgressEvent; import com.aliyun.oss.event.ProgressEventType; import com.aliyun.oss.event.ProgressListener; import com.aliyun.oss.model.GetObjectRequest; import com.aliyun.oss.model.OSSObject; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class OSSDownloadWithProgress { private static final String ACCESS_KEY_ID = "<yourAccessKeyId>"; private static final String ACCESS_KEY_SECRET = "<yourAccessKeySecret>"; private static final String ENDPOINT = "<yourEndpoint>"; private static final String BUCKET_NAME = "<yourBucketName>"; private static final String OBJECT_KEY = "<yourObjectKey>"; private static final String DOWNLOAD_FILE_NAME = "<yourDownloadFileName>"; private static final int THREAD_POOL_SIZE = 5; public static void main(String[] args) { // 创建OSSClient实例 OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET); // 创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE); // 创建GetObjectRequest对象并设置进度监听器 GetObjectRequest getObjectRequest = new GetObjectRequest(BUCKET_NAME, OBJECT_KEY); getObjectRequest.setProgressListener(new ProgressListener() { private long bytesWritten = 0; private long totalBytes = -1; private boolean succeed = false; @Override public void progressChanged(ProgressEvent progressEvent) { long bytes = progressEvent.getBytes(); ProgressEventType eventType = progressEvent.getEventType(); switch (eventType) { case TRANSFER_STARTED_EVENT: System.out.println("Start to download..."); break; case RESPONSE_CONTENT_LENGTH_EVENT: this.totalBytes = bytes; System.out.println(this.totalBytes + " bytes in total will be downloaded to a local file"); break; case RESPONSE_BYTE_TRANSFER_EVENT: this.bytesWritten += bytes; if (this.totalBytes != -1) { int percent = (int) (this.bytesWritten * 100.0 / this.totalBytes); System.out.println(bytes + " bytes have been written at this time, download progress: " + percent + "% (" + this.bytesWritten + "/" + this.totalBytes + ")"); } else { System.out.println(bytes + " bytes have been written at this time, download ratio: unknown" + "(" + this.bytesWritten + "/...)"); } break; case TRANSFER_COMPLETED_EVENT: this.succeed = true; System.out.println("Succeed to download, " + this.bytesWritten + " bytes have been transferred in total"); break; case TRANSFER_FAILED_EVENT: System.out.println("Failed to download, " + this.bytesWritten + " bytes have been transferred"); break; default: break; } } }); // 提交下载任务到线程池 executorService.submit(() -> { try { // 下载OSS文件到本地 OSSObject ossObject = ossClient.getObject(getObjectRequest); BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent()); File file = new File(DOWNLOAD_FILE_NAME); FileOutputStream out = new FileOutputStream(file); byte[] buffer = new byte[8192]; int len; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); } out.close(); in.close(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭OSSClient和线程池 ossClient.shutdown(); executorService.shutdown(); } }); } } ``` 在上面的代码中,我们通过创建GetObjectRequest对象并设置进度监听器来实现OSS文件的下载进度显示。然后,我们将下载任务提交到线程池中,并在下载完成后关闭OSSClient和线程池。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值