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

结果和第一篇一样。
原理:在第一篇的基础上添加了存储每个线程的下载进度的临时文件,当全部的线程都下载好的时候,将存储下载进度的临时文件删除

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class M1 {

    //下载一个文件的线程数
    public static int count = 3;

    public static String basePath = "C:\\Users\\shixing\\Desktop\\haha\\";
    //本地临时文件path
    public static String localPath = basePath + "33.jpg";

    //下载地址,你替换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";

    //the number of thread finished.
    public static int currentFinished = 0;
    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(localPath);
                //创建随机文件存储对象
                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 {
            File fileProcess = new File(M1.basePath + this.threadId + ".txt");
            int currentPosition = this.startIndex;
            if(fileProcess.exists()) {
                BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(new FileInputStream(fileProcess)));
                this.startIndex = Integer.parseInt(bufferedReader.readLine());
                currentPosition = this.startIndex;
                bufferedReader.close();
                System.out.println("线程" + threadId  + "的开始位置:" + startIndex
                        +"-------结束位置:" + endIndex);
            }
            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.localPath);
                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);
                    currentPosition = startIndex + total;
                    RandomAccessFile rafProcessFile = new RandomAccessFile(fileProcess, "rwd");
                    rafProcessFile.writeBytes(currentPosition + "");
                    rafProcessFile.close();
                }

                raf.close();
                System.out.println("线程" + threadId + "下载完毕----------");
                M1.currentFinished++;
                synchronized (M1.class) {
                    if(M1.currentFinished == M1.count) {
                        for(int i = 0; i < M1.count; ++i) {

                            File tempFile = new File(M1.basePath + i + ".txt");
                            if(tempFile.exists()) {
                                tempFile.delete();
                            }
                        }
                        M1.currentFinished = 0;
                    }
                }

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



}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值