• java多线程断点下载原理(代码实例演示)


    原文:http://www.open-open.com/lib/view/open1423214229232.html

      其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载,首先:你必须明白第一点,那么就是,什么是多线程下载,该知识点可以查看本博客上一篇文章,Android之多线程下载原理,断点下载呢,其实就是在这个的基础之上添加了一些东西,那么添加了什么东西了,现在来做一个详细的了解。

    1.在下载的过程中,边下载,变用一个文件来记录下载的位置,也就是下载了多少的数据

    1.创建文件

    2.记录下载多少数据

    3.存储数据

    2.第二次下载的时候,就去读取文件中是否存有数据,读取上次下载的位置,作为这次开始下载的位置

    1.创建文件对象

    2.检验是否有次文件和文件里面是否有数据

    3.读取数据,将数据拿给这次的开始位置,也就是从这个数据这里开始下载

    3.文件下载完成之后,将记录的文件删除,一定要下载完成之后,在将文件删除,不然会跳出一些异常,比如,这次文件没了,就要重新开始下载等等

    4.以上说了这些是不是稍微明白了些,那么下面来看看真正的实践吧

    示例源码:

        import java.io.File;  
        import java.io.FileInputStream;  
        import java.io.InputStream;  
        import java.io.RandomAccessFile;  
        import java.net.HttpURLConnection;  
        import java.net.URL;  
          
          
        /** 
         * 文件下载器 
         *  
         * @author Administrator zengtao 
         *  
         */  
        public class DemoLoader {  
        private static DemoLoader loader = new DemoLoader();  
        private static int threadCount = 3;  
        private static int runningThread = 3;  
          
          
        private DemoLoader() {  
          
          
        }  
          
          
        public static DemoLoader getInstance() {  
        return loader;  
        }  
          
          
        /** 
        * 去服务器端下载文件 
        *  
        * @param path 
        *            服务器地址 
        */  
        public void downFile(String path) {  
        // 去服务器端获取文件的长度,在本地创建一个跟服务器一样大小的文件  
        try {  
        URL url = new URL(path);  
        HttpURLConnection connection = (HttpURLConnection) url  
        .openConnection();  
        connection.setDoInput(true);  
        connection.setRequestMethod("GET");  
        connection.setReadTimeout(5000);  
        int code = connection.getResponseCode();  
        if (code == 200) {  
        // 1.获取服务器端文件的长度  
        int fileLength = connection.getContentLength();  
        // 2.本地创建一个跟服务器一样大小的文件  
        RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");  
        raf.setLength(fileLength);  
        raf.close();  
        // 3.假设三个线程下载  
        int blockSize = fileLength / threadCount;  
        for (int threadId = 0; threadId < threadCount; threadId++) {  
        int startIndex = (threadId - 1) * blockSize;  
        int endIndex = threadId * blockSize - 1;  
        if (threadId == threadCount) {  
        endIndex = fileLength;  
        }  
          
          
        // log 假设下载  
        System.out.println("假设线程:" + threadId + ",下载:" + startIndex  
        + "--->" + endIndex);  
        // 4.开始下载  
        new DownLoadThread(threadId, startIndex, endIndex, path)  
        .start();  
        }  
        System.out.println("文件总长度为:" + fileLength);  
        } else {  
        System.out.println("请求失败!");  
        }  
          
          
        } catch (Exception e) {  
        e.printStackTrace();  
        }  
        }  
          
          
        /** 
        * 下载文件的线程 
        *  
        * @author Administrator zengtao 
        *  
        */  
        public class DownLoadThread extends Thread {  
        private int threadId;  
        private int startIndex;  
        private int endIndex;  
        private String path;  
          
          
        /** 
        *  
        * @param threadId 
        *            线程id 
        * @param startIndex 
        *            线程下载开始位置 
        * @param endIndex 
        *            线程下载结束位置 
        * @param path 
        *            线程下载结束文件放置地址 
        */  
        public DownLoadThread(int threadId, int startIndex, int endIndex,  
        String path) {  
        super();  
        this.threadId = threadId;  
        this.startIndex = startIndex;  
        this.endIndex = endIndex;  
        this.path = path;  
        }  
          
          
        @Override  
        public void run() {  
        super.run();  
        try {  
        // 1.检验是否有存的记录 -------------------------------------------------------------------------------------------------  
        File file = new File(threadId + ".txt");  
        if (file.exists() && file.length() > 0) {  
        FileInputStream fis = new FileInputStream(file);  
        byte[] temp = new byte[1024];  
        int leng = fis.read(temp);  
        String loadLength = new String(temp, 0, leng);  
        int load = Integer.parseInt(loadLength);  
        startIndex = load;  
        fis.close();  
        }  
        URL url = new URL(path);  
        HttpURLConnection connection = (HttpURLConnection) url  
        .openConnection();  
        // 2.请求服务器下载部分的文件,制定开始的位置,和结束位置  
        connection.setRequestProperty("Range", "bytes=" + startIndex  
        + "-" + endIndex);  
        // log 真实下载  
        System.out.println("真实线程:" + threadId + ",下载:" + startIndex  
        + "--->" + endIndex);  
        connection.setDoInput(true);  
        connection.setRequestMethod("GET");  
        connection.setReadTimeout(5000);  
        // 3.从服务器获取的全部数据,返回:200,从服务器获取部分数据,返回:206  
        int code = connection.getResponseCode();  
        System.out.println("code = " + code);  
        InputStream is = connection.getInputStream();  
        RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");  
        raf.seek(startIndex); // 随机写文件的时候,从什么时候开始  
        int len = 0;  
        int total = 0; // 记录下载多少  -----------------------------------------  
        byte[] buff = new byte[1024];  
        while ((len = is.read(buff)) != -1) {  
        RandomAccessFile info = new RandomAccessFile(threadId  
        + ".txt", "rwd");  
        raf.write(buff, 0, len);  
        total += len;  
        info.write(("" + startIndex + total).getBytes()); // 4.存数据:(真正下载到开始的位置)下载的+开始的----------------------------------------  
        info.close();  
        }  
        is.close();  
        raf.close();  
        System.out.println("线程:" + threadId + ",下载完成");  
        } catch (Exception e) {  
        e.printStackTrace();  
        } finally {  
        // 5.notice一定要文件都下载完毕之后再将记录文件删除  
        runningThread--;  
        if (runningThread == 0) {  
        for (int i = 1; i <= threadCount; i++) {  
        File file = new File(i + ".txt");  
        file.delete();  
        }  
        System.out.println("文件下载完毕,删除记录文件"); ---------------------------------------------------------------------  
        }  
        }  
        }  
        }  
        }  
  • 相关阅读:
    OLAP ODS项目的总结 平台选型,架构确定
    ORACLE ORA12520
    ORACLE管道函数
    ORACLE RAC JDBC 配置
    ORACLE RAC OCFS连接产生的错误
    ORACLE 启动和关闭详解
    OLAP ODS项目的总结 起步阶段
    ORACLE RAC 配置更改IP
    ORACLE RAC OCR cann't Access
    ORACLE RAC Debug 之路 CRS0184错误与CRS初始化
  • 原文地址:https://www.cnblogs.com/shihaiming/p/6993326.html
Copyright © 2020-2023  润新知