首页 > 代码库 > java 多线程断点下载功能

java 多线程断点下载功能

import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;public class Demo {        //线程个数    public static int threadCount = 3;        //线程下载完成的个数    public static int finishedCount = 3;    /**     * 多线程下载测试类     * @param args     * @throws Exception      */    public static void main(String[] args) throws Exception {                //1、连接服务器,获取一个文件,获取文件的长度,在本地创建一个大小跟服务器文件一样大的临时文件        String path = "http://192.168.1.100:8080/test.avi";        URL url = new URL(path);        HttpURLConnection conn = (HttpURLConnection)url.openConnection();        conn.setConnectTimeout(5000);        conn.setRequestMethod("GET");        int code = conn.getResponseCode();        if(code==200)        {                        //服务器返回的数据长度 实际上就是文件的长度            int length = conn.getContentLength();            System.out.println("文件总长度:"+length);                        //在客服端创建出来一个大小跟服务器端文件一样大小的临时文件            RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");            //指定创建的这个文件的长度            raf.setLength(length);            raf.close();                                    //假设是3个线程去下载资源            //平均每一个线程下载的文件的大小            int blockSize = length / threadCount;            for(int threadId=1;threadId<=threadCount;threadId++)            {                //线程下载的开始位置                int startIndex = (threadId-1)*blockSize;                int endIndex = threadId*blockSize;                if(threadId==threadCount)                {                    endIndex = length;                                    }                System.out.println("线程:"+threadId+" 下载:---"+startIndex+"--->"+endIndex);                                //启动线程                new DownloadThread(threadId,startIndex,endIndex,path).start();            }                    }        else        {            System.out.println("服务器错误");        }            }        public static class DownloadThread extends Thread    {        private int threadId;  //线程id        private int startIndex;         private int endIndex;        private String path;                public DownloadThread(int threadId, int startIndex, int endIndex,                String path) {            super();            this.threadId = threadId;            this.startIndex = startIndex;            this.endIndex = endIndex;            this.path = path;        }        public void run() {            try {                                //检查是否存在记录文件下载长度的文件,如果存在读取这个文件的数据                                File tempFile = new File(threadId+".txt");                if(tempFile.exists() && tempFile.length() >0)                {                    FileInputStream fis = new FileInputStream(tempFile);                    byte[] temp = new byte[1024];                    int leng = fis.read(temp);                    String downloadLen = new String(temp,0,leng);                    int downloadLenInt = Integer.parseInt(downloadLen);                    startIndex = downloadLenInt;                    fis.close();                }                                System.out.println("线程:"+threadId+"实际下载:---"+startIndex+"--->"+endIndex);                                URL url = new URL(path);                HttpURLConnection conn =(HttpURLConnection) url.openConnection();                conn.setConnectTimeout(5000);                conn.setRequestMethod("GET");                                //重要 : 请求服务器下载部分的文件指定文件的位置                conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);                                //从服务器请求全部资源 200 ok 如果从服务器请求部分资源 206 ok                int code = conn.getResponseCode();                System.out.println("code:"+code);                                //已经设置了请求的位置 返回的事当前位置对应的文件的输入流                InputStream is = conn.getInputStream();                                //在客服端创建出来一个大小跟服务器端文件一样大小的临时文件                RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");                //随机写文件的时候从哪个位置开始                raf.seek(startIndex); //定位文件                                int len = 0;                byte[] buffer = new byte[1024];                int total = 0;                while((len=is.read(buffer))!=-1)                {                    //记录已经下载完成的长度                    RandomAccessFile recordFile = new RandomAccessFile(threadId+".txt","rwd");                    raf.write(buffer,0,len);                    //下载完成的长度                    total += len;                    recordFile.write((total+startIndex +"").getBytes());                    recordFile.close();                                    }                                is.close();                raf.close();                                System.out.println("线程:"+threadId+"下载完毕了。。。");                            } catch (Exception e) {                e.printStackTrace();            }finally            {                //用于删除各个线程记录已经下载完成的长度的文件                finishedCount--;                //所有线程下载完成                if(finishedCount==0)                {                                        for(int i=1;i<=threadCount;i++)                    {                        //删除记录文件                        File deleteFile = new File(i+".txt");                        deleteFile.delete();                    }                                    }                            }        }                    }}

 

java 多线程断点下载功能