JAVA 多线程下载单个资源

来源:互联网 发布:淘宝美之梦睡衣 编辑:程序博客网 时间:2024/05/16 02:23

小白自学到多线程,突发奇想,现在的网络下载工具都不怎么好用。
自己有时候还使用爬虫,就写了下基于http协议的多线程下载。
不到之处,还请各位谅解。

思路是:
1)先完成单线程下载
2)将单线程修改为多线程下载

单线程的例子我就不列举了,直接放多线程的,一共有两个类:下载文件工具类,和个人线程类

/** * 下载文件工具类 * Created by sumei on 17/8/8. */public class DownUtil {    /**     *     *  通过http协议从网络中下载文件到指定的目录下     * @param urlPath 网络资源地址     * @param targetPath 下载到指定目录的地址     * @param targetName 下载文件 , 指定文件名     * @param threadCount 线程总数,通过线程总数计算所需下载文件的大小     * @param threadNo  线程编号,通过计算获得所下载的文件对应的位置     */    public static void download ( String urlPath , String targetPath , String targetName , int threadCount , int threadNo ) {        InputStream in = null;        RandomAccessFile saf = null;        try {            // 初始化URL            URL url = new URL(urlPath);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            // 获取文件的总大小            long fileSize = conn.getContentLengthLong();            long length = fileSize / threadCount;            long begin = threadNo * length;            long end = threadCount - 1 != threadNo ? begin + length : fileSize ;            // 设置响应时长            conn.setConnectTimeout( 5 * 1000 );            // 获得网络资源的url            in = conn.getInputStream();            // 跳过指定的位置            in.skip(begin);            File file = new File(targetPath);            if ( !file.exists() ) {                file.mkdirs();            }            // 创建输出流            saf = new RandomAccessFile( targetPath + targetName , "rw");            // 从文件的指定位置开始输出            saf.seek(begin);            int len;            byte[] buf = new byte[ 1024 * 8 ];            // 判断            long count = begin ;            while ( -1 != ( len = in.read(buf) ) && count < end) {                count += len;                saf.write( buf , 0 , len );            }            System.out.println("线程" + threadNo + "文件下载成功," + ( count - begin ) );        } catch (IOException e) {            e.printStackTrace();        } finally {            if ( null != in ) {                try {                    in.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            if ( null != saf ) {                try {                    saf.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }}

以下是:个人线程类

/** * 继承Thread类,实现个人线程类 * Created by sumei on 17/8/8. */public class DownThread extends Thread{    // 线程编号    private int threadNo;    // 线程总数    private int threadCount;    // 网络资源地址    private String srcPath;    // 下载文件的指定文件名    private String targetName;    // 下载的文件目录    private String targetPath;    public DownThread(int threadNo, int threadCount, String srcPath, String targetName, String targetPath) {        this.threadNo = threadNo;        this.threadCount = threadCount;        this.srcPath = srcPath;        this.targetName = targetName;        this.targetPath = targetPath;    }    @Override    public void run() {        DownUtil.download(srcPath,targetPath,targetName,threadCount,threadNo);    }}

测试代码:小部分的,写在main方法中。想尝试的同学,还需要定义targetName,url,和targetPath.
分别是下载文件url路径,下载文件到硬盘的路径目录,和新文件名。

   // 个人喜欢 5 个 线程        int threadCount = 5;        for ( int i = 0 ; i < threadCount ; i++ ) {            // 创建线程,开始启动            new DownThread(i,threadCount,url,targetName,targetPath).start();        }

不到之处,请大家指出,勉励,共同进步。

原创粉丝点击