zoukankan      html  css  js  c++  java
  • 断点续传(大文件的下载)后台功能实现

    某网盘

    • 可以随时暂停、启动
    • 多任务
    • 下载过程中、由于某一些特殊原因(宕机、断电、断网等),导致文件下载失败
      • 再一次下载的时候,还可以继续在原来的基础上下载
      • 当上一次下载的20%,再一次下载的时候,从20%继续下载
    • 本地都会产生一个临时数据文件
      • 中断后,文件不会消失

    断点续传

    原理:

    实现:

    长连接:socket、urlconnection、http、okhttp、httpclient

    思路:

    • 指定URL
    • 建立一个目录(指定临时文件)
    • 从服务器中获取对象流
    • 告诉服务器从哪个位置下标,开始发送数据
    • 将对象流对象,写入到临时文件中
    • 根据读取到的对象流长度来进行定义
    • 如果长度有值,则进行写入
    • 如果长度=-1,则无需进行写入操作

    代码:

    /**
     *
     * @author: likang
     * @date: 2019/12/5 20:44
     * @description: 断点续传(仿百度网盘下载功能)
     */
    public class FileDownLoadUtils {
    
        public static void main(String[] args) {
            //指定URL
            String url = "http://mirrors.aliyun.com/centos/8.0.1905/isos/x86_64/CentOS-8-x86_64-1905-dvd1.iso";
            //下载文件
            downLoadFile(url);
        }
    
        /*
         * @Description: 创建文件
         * @author: likang
         * @date: 2019/12/5 20:47
         * @params: [url]
         * @return: void
         * @exception:
         */
        private static void downLoadFile(String url) {
            //指定本地下载的目录地址
            File file = new File(FileDownLoadUtils.class.getResource("").getFile());
            //        //生成一个临时文件(目的:主要是记录数据的下标位置(字节长度))
            //        //getAbsolutePath:获取绝对路径
            //        //separator:自动识别当前系统资源分割符合
    
            file = new File(file.getAbsolutePath() + File.separator + "CentOS-8-x86_64-1905-dvd1.iso.bak");
            //如果目录不存在,则创建
            if(!file.exists()){
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //将url中的数据流对象,写入到临时文件中file
            writeFile(url,file);
    
        }
    
        /*
         * @Description: 通过url获取服务器对象流,并写入到文件中file
         * @author: likang
         * @date: 2019/12/5 21:00
         * @params: [url, file]
         * @return: void
         * @exception:
         */
        private static void writeFile(String url, File file) {
    
            byte[] bytes = new byte[1024*1024];
            //定义流对象
            InputStream inputStream = null;//数据流
            FileOutputStream fileOutputStream = null;//写入file对象数据流
            long fileLength = 0;
            int byteCount = 0;
            //根据URL和服务器建立连接---数据流
            try {
                fileOutputStream = new FileOutputStream(file, true);
                fileLength = file.length();
                //建立连接,获取对象流
                inputStream = getInputStream(url,fileLength);
    //            byteCount = inputStream.read(bytes);
    //            while(byteCount != -1){
    //                //数据流---file文件中(临时文件)
    //                fileOutputStream.write(bytes, 0, byteCount);
    //            }
                while((byteCount = inputStream.read(bytes)) != -1){
                    //数据流---file文件中(临时文件)
                    fileOutputStream.write(bytes, 0, byteCount);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                 //关闭流对象
                try {
                    inputStream.close();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
    
    
        }
    
        /*
         * @Description: 建立连接、获取对象流
         * @author: likang
         * @date: 2019/12/5 21:18
         * @params: [url, fileLength]
         * @return: java.io.InputStream
         * @exception:
         */
        private static InputStream getInputStream(String url, long startFileLength) {
            InputStream inputStream = null;
            HttpURLConnection connection;
    
            try {
                URL filePath = new URL(url);//和服务器建立连接、获取文件路径
                connection = (HttpURLConnection) filePath.openConnection();//开启连接
                connection.setConnectTimeout(3*1000);//连接超时时间
                long lengthLong = connection.getContentLengthLong();//文件的总长度
                if(startFileLength < lengthLong){//还没下载完毕
                    connection.disconnect();//销毁链接
                    connection = (HttpURLConnection) filePath.openConnection();//开启连接
                    connection.setConnectTimeout(3*1000);//连接超时时间
                    connection.setRequestProperty("RANGE", "bytes=" + startFileLength + "-");//设置请求发送下标的对象
                    System.out.println(connection.getContentLengthLong());
                    inputStream = connection.getInputStream();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return inputStream;
    
        }
    
    }
  • 相关阅读:
    poj1661【DP,左右两端dp】
    hdoj1074【A的无比爆炸】
    hdoj1024【DP.最 大 m 字 段 和】(写完我都怕。。。不忍直视。。)
    qq教xixi写模拟加法【非常爆炸】
    错排公式
    POJ3616【基础DP】
    hdoj1257【疑问】(贪心)
    【弱的C艹之路。。未完待续】
    hdoj1728【搜索的两种写法】
    hdoj1001【智障了。。。】
  • 原文地址:https://www.cnblogs.com/fangts/p/15007778.html
Copyright © 2011-2022 走看看