多线程下载

来源:互联网 发布:淘宝去哪里设置首页 编辑:程序博客网 时间:2024/05/16 03:42
package com.zhaoda.zxy.myapplication;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;/** * Created by ZXY on 2016/5/23. */public class MutilDownload2 {    //[1]定义h下载路径    private static String path = "http://172.17.242.1:8080/as.exe";    private static final int threadCount = 3;//假设开三个线程    private static int runningThread;//代表当前正在运行的线程    public static void main(String[] args) {//[一☆☆☆☆☆]获取服务器文件大小,要计算每个线程的下载开始的位置和结束位置        try {            //1.创建url对象参数就是网址            URL url = new URL(path);            //2.获取HttpURLConnecton链接对象            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            //3.设置参数发送get请求            conn.setRequestMethod("GET");            //4.设置链接网路的超时时间            conn.setConnectTimeout(5000);            //5.获取服务器返回状态码            int code = conn.getResponseCode();            if (code == 200) {//200代表获取服务器资源全部成功,206请求部分资源                //6.获取服务器文件的大小                int length = conn.getContentLength();                //6.1把线程的数量赋给正在运行的线程                runningThread = threadCount;                //[二☆☆☆☆☆]创建大小和服务器一模一样的文件目的提前把空间申请出来                RandomAccessFile raf = new RandomAccessFile("temp.exe", "rw");                raf.setLength(length);                //7.算出每个线程下载的大小                int blockSize = length / threadCount;                //[三☆☆☆☆☆]计算每个线程开始位置和结束位置                for (int i = 0; i < threadCount; i++) {                    int startIndex = i * blockSize;//每个线程下载开始位置                    int endIndex = (i + 1) * blockSize - 1;                    if (i == threadCount - 1) {                        //说明是最好一个线程                        endIndex = length - 1;                    }                    System.out.println("线程id:" + i + "理论下载位置" + ":" + startIndex + "----" + endIndex);                    //[四☆☆☆☆☆]开启线程去服务器下载文件                    DownLoadThread downLoadThread = new DownLoadThread(startIndex, endIndex, i);                    downLoadThread.start();                }            }        } catch (Exception e) {            e.printStackTrace();        }    }    //定义线程去服务器下载文件    private static class DownLoadThread extends Thread {        //通过构造方法把每个线程下载的开始位置和结束位置        private int startIndex;        private int endIndex;        private int threadId;        public DownLoadThread(int startIndex, int endIndex, int threadId) {            this.startIndex = startIndex;            this.endIndex = endIndex;            this.threadId = threadId;        }        @Override        public void run() {            //实现去服务器下载文件的逻辑            try {                //1.创建url对象参数就是网址                URL url = new URL(path);                //2.获取HttpURLConnecton链接对象                HttpURLConnection conn = (HttpURLConnection) url.openConnection();                //3.设置参数发送get请求                conn.setRequestMethod("GET");                //4.设置链接网路的超时时间                conn.setConnectTimeout(5000);                //4.0如果下载中间断过,继续上次的位置继续下载,从文件中读取上次下载的位置                File file = new File(getFilename(path) + threadId + ".txt");                if (file.exists() && file.length() > 0) {                    FileInputStream fis = new FileInputStream(file);                    BufferedReader bufr = new BufferedReader(new InputStreamReader(fis));                    String lastPositionn = bufr.readLine();//读取出来内容就是上次下载位置                    int lastPosition = Integer.parseInt(lastPositionn);                    //4.0.1要改变startIndex位置                    startIndex = lastPosition;                    System.out.println("线程id:" + threadId + "真实下载位置" + ":" + startIndex + "----" + endIndex);                    fis.close();                }                //4.1设置一个请求头Range(作用告诉服务器每个线程下载的开始位置和结束位置)                conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);                //5.获取服务器返回状态码                int code = conn.getResponseCode();                if (code == 206) {//200代表获取服务器资源全部成功,206请求部分资源                    //6.创建随机读写文件对象                    RandomAccessFile raf = new RandomAccessFile(getFilename(path), "rw");                    //6.1每个线程都从自己位置开始写                    raf.seek(startIndex);                    InputStream in = conn.getInputStream();//获取服务器文件                    //7.把数据写到文件中.                    int len = -1;                    byte[] buffer = new byte[1024 * 1024];                    int total = 0;//当前线程下载的大小                    while ((len = in.read(buffer)) != -1) {                        raf.write(buffer, 0, len);                        total += len;                        //8.实现断点续传就是把当前线程下载的位置存起来,下次再下载就是按照上次下载位置继续下载就行了                        int currrentThreadPosition = startIndex + total;//占时存在txt文本中                        //q.用来存当前线程下载的位置                        RandomAccessFile raff = new RandomAccessFile(getFilename(path) + threadId + ".txt", "rwd");                        raff.write(String.valueOf(currrentThreadPosition).getBytes());                        raff.close();                    }                    raf.close();//关闭流,释放资源                    System.out.println("线程id:" + threadId + "下载完毕!");                    //10.把.txt文件删除                    synchronized (DownLoadThread.class) {                        runningThread--;                        if (runningThread == 0) {                            //说明所有线程都执行完毕了,就把.txt文件删除了                            for (int i = 0; i < threadCount; i++) {                                File delteFile = new File(getFilename(path) + i + ".txt");                                delteFile.delete();                            }                        }                    }                }            } catch (Exception e) {                e.printStackTrace();            }        }    }    //获取文件的名字  http://172.17.242.1:8080/as.exe    public static String getFilename(String path) {        int start = path.lastIndexOf("/") + 1;        return path.substring(start);    }}
0 0
原创粉丝点击