JAVA 多线程下载单个资源

小白自学到多线程,突发奇想,现在的网络下载工具都不怎么好用。
自己有时候还使用爬虫,就写了下基于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();
        }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值