首页>代码>java多线程下载文件神器,有下载进度>/ideaWorkSpace/src/DownloadUtil.java
/**
 * FileName: DownloadUtil
 * Author:   梁庆昌
 * Date:     2018/3/21 10:52
 * Description:多线程下载文件
 */


import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;


public class DownloadUtil {
    // 定义成员变量
    private String path; // 远程资源路径
    private String targetPath; // 本地存储路径
    private DownFileThread[] threads; // 线程list
    private int threadNum; // 线程数量
    private long length; // 下载的文件大小

    // 构造初始化
    public DownloadUtil(String path, String targetPath, int threadNum) {
        super();
        this.path = path;
        this.targetPath = targetPath;
        this.threads = new DownFileThread[threadNum];
        this.threadNum = threadNum;
    }

    // 多线程下载文件资源
    public void download() {
        URL url;
        try {
            url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
            conn.setRequestMethod("GET");
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("accept", "*/*");

            // 获取远程文件的大小
            length = conn.getContentLength();
            conn.disconnect();

            // 设置本地文件大小
            RandomAccessFile targetFile = new RandomAccessFile(targetPath, "rw");
            targetFile.setLength(length);

            // 每个线程下载大小
            long avgPart = length / threadNum + 1;
            // 下载文件
            for (int i = 0; i < threadNum; i++) {
                long startPos = avgPart * i;
                RandomAccessFile targetTmp = new RandomAccessFile(targetPath,
                        "rw");
                targetTmp.seek(startPos); // 分段下载
                threads[i] = new DownFileThread(startPos, targetTmp, avgPart);
                threads[i].start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 监控下载进度
    public double getDownRate() {
        int currentSize = 0;
        for (int i = 0; i < threadNum; i++) {
            currentSize += threads[i].length;
        }
        return currentSize * 1.0 / length ;
    }

    // 定义线程类
    class DownFileThread extends Thread {
        private long startPos;
        private RandomAccessFile raf;
        private long size;
        private long length;

        public DownFileThread(long startPos, RandomAccessFile raf, long size) {
            super();
            this.startPos = startPos;
            this.raf = raf;
            this.size = size;
        }
        @Override
        public void run() {
            URL url;
            try {
                url = new URL(path);
                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
                conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
                conn.setRequestMethod("GET");
                conn.setRequestProperty("connection", "keep-alive");
                conn.setRequestProperty("accept", "*/*");

                InputStream in = conn.getInputStream();
                in.skip(this.startPos);
                byte[] buf = new byte[1024];
                int hasRead = 0;
                while (length < size && (hasRead = in.read(buf)) != -1) {
                    raf.write(buf, 0, hasRead);
                    length += hasRead;
                }
                raf.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 测试
    public static void main(String[] args) {
        String path = "http://ftp-idc.pconline.com.cn/956b950ead9d83001388407babb2f47c/pub/download/201010/65.0.3325.162_chrome_installer.exe";
        String targetPath = "D:/1.exe";
        final DownloadUtil download = new DownloadUtil(path, targetPath, 4);
        download.download();
        // 主线程负责下载文件,在启动一个线程负责监控下载的进度
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (download.getDownRate() < 1) {
                    System.out.println(String.format("%.1f",download.getDownRate()*100)+"%");
                    try {
                        Thread.sleep(1000); // 200毫秒扫描一次
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }).start();
    }
}
最近下载更多
bai620123  LV16 2022年4月16日
Kervin  LV11 2021年6月3日
花椒谢霆锋  LV8 2021年3月15日
616032899  LV1 2021年2月18日
zhenghongixin4065  LV9 2021年1月25日
hulinyun  LV2 2020年8月1日
fengyedream  LV1 2020年7月21日
lyd19931203  LV21 2020年6月12日
liuyilin9608  LV15 2020年5月17日
dreamfitle  LV4 2019年9月6日
最近浏览更多
dixiu000  LV4 2023年4月14日
wananall  LV13 2022年10月21日
heqian  LV17 2022年10月17日
MoonSight  LV1 2022年7月1日
xuexizhuanyong23  LV16 2022年6月29日
crosa_Don  LV18 2022年6月7日
我不划水 2022年5月13日
暂无贡献等级
zjw1997 2022年4月30日
暂无贡献等级
liys1234  LV9 2022年4月27日
szf123  LV12 2022年4月22日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友