1 多线程下载一个文件(普通的java工程:java实现)

原理图:
这里写图片描述
结果图:
这里写图片描述
这里写图片描述

代码如下:

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

public class M1 {

    //下载一个文件的线程数
    private static int count = 3;
    //下载地址,你替换path的网址就行了
    public static String path = "https://img-blog.csdn.net/20160130160136042?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center";
    public static void main(String[] args) {

        URL url;
        try {
            url = new URL(path);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setRequestMethod("GET");
            connection.setReadTimeout(5000);
            connection.setConnectTimeout(5000);
            if(connection.getResponseCode() == 200) {
                //拿到要下载文件的大小
                int length = connection.getContentLength();

                //指定临时文件的路径和文件名
                File file = new File(getFileName(path));
                //创建随机文件存储对象
                RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                //创建临时文件的大小,和服务器文件一模一样
                raf.setLength(length);

                //计算每个线程下载的字节数
                int size = length / count;
                for(int i = 0; i < count; ++i) {
                    //计算3个线程下载数据的开始位置和结束位置
                    int startIndex = i * size;
                    int endIndex = (i + 1) * size - 1;
                    //如果是最后一个线程,name结束位置做特殊处理
                    if(i == count - 1) {
                        endIndex = length - 1;
                    }
                    System.out.println("线程" + i  + "的开始位置:" + startIndex
                            +"-------结束位置:" + endIndex);
                    new MyDownloadThread(i, startIndex, endIndex).start();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static String getFileName(String path2) {
        int index = path2.lastIndexOf("/");
        return path2.substring(index + 1);
    }

}
class MyDownloadThread extends Thread {

    int threadId;
    int startIndex;
    int endIndex;


    public MyDownloadThread(int i, int startIndex, int endIndex) {
        this.threadId = i;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }

    @Override
    public void run() {
        try {
            URL url = new URL(M1.path);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setRequestMethod("GET");
            connection.setReadTimeout(5000);
            connection.setConnectTimeout(5000);
            //设置请求数据的范围
            connection.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
            //206说明请求的是部分数据,而200是请求的全部数据
            if (connection.getResponseCode() == 206) {
                InputStream inputStream = connection.getInputStream();
                byte[] b = new byte[1024];
                //当前下载的总子节数
                int total = 0;
                int len = 0;
                //指定临时文件的路径和文件名
                File file = new File(M1.getFileName(M1.path));
                RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                //设置线程从哪个位置开始写入数据到临时文件
                raf.seek(startIndex);
                while((len = inputStream.read(b)) != -1) {
                    raf.write(b,0,len);
                    total += len;
                    System.out.println("线程" + threadId + " 已经下载" + total);
                }

                raf.close();
                System.out.println("线程" + threadId + "下载完毕----------");

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值