美文网首页java核心知识Java知识123程序员
JAVA多线程下载,断点续传(HTTP)

JAVA多线程下载,断点续传(HTTP)

作者: 奔跑的笨鸟 | 来源:发表于2016-05-13 18:46 被阅读1339次

    HTTP的断点续传其实很简单,就是通过设置Header (RANGE: bytes=XXXXXXXX- )

    1, 通常的HTTP请求

    <pre>
    `
    public static void main(String[] args) {

        try {
            URL url = new URL("http://mirrors.cnnic.cn/apache/abdera/1.1.3/apache-abdera-1.1.3-bin.zip");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            //con.setRequestProperty("RANGE", "bytes=100-");
            con.setRequestMethod("HEAD");
            con.connect();
            Map<String, List<String>> header = con.getHeaderFields();
            Iterator<String> keyIt = header.keySet().iterator();
            while(keyIt.hasNext()){
                String key = keyIt.next();
                List<String> values = header.get(key);
                System.out.print(key+":");
                for (String value:values) {
                    System.out.print(value);
                    
                }
                System.out.println();
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    `
    </pre>
    这时候的输出:
    <p>
    Last-Modified:Sat, 14 Jun 2014 16:32:17 GMT
    null:<b>HTTP/1.1 200 OK</b>
    Server:nginx
    ETag:"539c7911-d21551"
    Content-Length:13768017
    Accept-Ranges:bytes
    Connection:keep-alive
    Content-Type:application/zip
    Date:Fri, 13 May 2016 09:58:20 GMT
    </p>
    返回的相应码是200,

    2,在请求的HEAD中添加RANGE:bytes=XXXXX-

    如果添加con.setRequestProperty("RANGE", "bytes=100-");
    下面是输出结果:
    <p>
    Last-Modified:Sat, 14 Jun 2014 16:32:17 GMT
    null:<b>HTTP/1.1 206 Partial Content</b>
    Server:nginx
    ETag:"539c7911-d21551"
    Content-Range:bytes 100-13768016/13768017
    Content-Length:13767917
    Connection:keep-alive
    Content-Type:application/zip
    Date:Fri, 13 May 2016 10:00:16 GMT
    </P>

    这次的响应码是206, 并且在response中返回了Content-Range:bytes 100-13768016/13768017
    这个100-13768016是这个可以下载的大小,13768017是文件大小。此时的Content-Length:13767917不是文件大小,而是13768016-100=13767917,此时可以下载的大小。

    3, 多线程下载文件

    多线程下载的原理就是,多个线程同时发送请求通过在head 添加RANGE:bytes=XXXXX-
    比如线程1设置RANGE:bytes=1000-,线程2设置RANGE:bytes=2000- 等等

    4,断点续传

    断点续传是把每个线程下的位置保存一个文件,下次在请求的时候从没有下载的地方开始

    5,简单实现

    程序结构:

    multithread.png

    源码:github
    测试代码:
    <p>
    <pre>

    public static void main(String[] args) {
    DownLoader dl = DownLoader.getInstance();
    dl.setUrl("http://mirrors.cnnic.cn/apache/abdera/1.1.3/apache-abdera-1.1.3-bin.zip");
    dl.setOnDownLoadListener(new DownLoaderListener() {

            @Override
            public void onError(String arg0) {
                System.out.println(arg0);
            }
    
            @Override
            public void onFinish(String arg0) {
                System.out.println(arg0);
            }
    
            @Override
            public void onUpgrade(float arg0) {
                System.out.println(arg0);
    
            }
        });
    
        dl.setThreadCount(3);
        dl.start();
    }
    

    </pre>

    </p>
    程序有很多不足,请多多指教,谢谢!

    相关文章

      网友评论

      • high_m:想问下有没有考虑过如和通过浏览器断点续传下载?谁来发送Header中的Range?断网之后如何断点续传?暂停一段时间(1分钟)后如何断点续传?
        奔跑的笨鸟:@high_m 浏览器的可能有本地缓存的下载状态数据,有时间看下,共同学习。
        high_m:这我知道,就是想知道断网后或者暂停时间过长后,如何断点续传?Header中的Range浏览器在断网或暂停后如何处理?我目前在弄这个东西,目前没有搞定,如果你有web测试通过,请回复我,共同学习一下,谢谢:smile:
        奔跑的笨鸟:@high_m 浏览器应该支持的,但首先服务器必须支持
      • 一个理想主义的大兵:怎么后边的markdown没有解析?
        奔跑的笨鸟: @一个理想主义的大兵 有时间再弄弄
      • 四大爷:mark 一下

      本文标题:JAVA多线程下载,断点续传(HTTP)

      本文链接:https://www.haomeiwen.com/subject/fahmrttx.html