影响下载的速度

* 宽带的带宽

* 服务器的限制

* 服务器的资源固定,开启的线程越多抢占的资源就越多

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

public class MultiDownLoad {

   static String path = http://192.168.3.100:8080/web/download/gui.exe;
static int threadCount = 3; /**
* 获取文件的存储路径
*/ static String getFilePath(){ int index = path.lastIndexOf("/")+1; return "D:\\"+path.substring(index); }
public static void main(String[] args) { try {
// 1. 在客户端创建和服务器资源一样大小的空文件 URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(3000); conn.setRequestMethod("GET"); int code = conn.getResponseCode(); //服务器资源文件的大小 int fileLength = 0; if (code == 200) { fileLength = conn.getContentLength(); System.out.println("文件大小:"+fileLength); // //可选,可以不写,检测硬盘的空间够不够用 // RandomAccessFile raf = new RandomAccessFile(getFilePath(), "rw"); // //在硬盘上创建控件 // raf.setLength(fileLength); // raf.close(); } //每个线程下载的区块大小 int blockSize = fileLength / threadCount; // 2. 客户端开启多个线程去下载服务器的资源 for (int threadId = 0; threadId < threadCount; threadId++) { int startIndex = threadId * blockSize; int endIndex = (threadId + 1)* blockSize -1; //最后一个线程,修正下载的结束位置 if (threadId == threadCount-1) { endIndex = fileLength - 1; } //开启线程 new DownLoadThread(startIndex, endIndex, threadId).start(); } } catch (Exception e) { e.printStackTrace(); } } static class DownLoadThread extends Thread { //开始位置 int startIndex; //结束位置 int endIndex; //线程ID int threadId; public DownLoadThread(int startIndex, int endIndex, int threadId) { super(); this.startIndex = startIndex; this.endIndex = endIndex; this.threadId = threadId; } @Override public void run() { super.run(); System.out.println("线程 : "+ threadId + " : "+ startIndex+" ~ "+endIndex); try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(3000); //重要,设置请求的范围 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); //部分请求成功 206 int code = conn.getResponseCode(); System.out.println(" code = "+code); if (code == 206) { RandomAccessFile raf = new RandomAccessFile(getFilePath(), "rw"); //重要,写文件之前定位 raf.seek(startIndex); //获取这个线程对应的一块资源 InputStream is = conn.getInputStream(); byte[] buffer = new byte[1024*8]; int len = -1; while((len = is.read(buffer)) != -1){ raf.write(buffer, 0, len); } raf.close();
} // 3. 每个线程都下载完毕,整个资源就下载完了 System.out.println("线程 "+threadId+" 干完活了!"); } catch (Exception e) { e.printStackTrace(); } } } }

HttpURLConnection 多线程下载的更多相关文章

  1. 使用HttpURLConnection多线程下载

    1 import java.io.IOException; 2 import java.io.InputStream; 3 import java.io.RandomAccessFile; 4 imp ...

  2. 多线程下载 HttpURLConnection

    Activity /**实际开发涉及文件上传.下载都不会自己写这些代码,一般会使用第三方库(如xUtils)或Android提供的DownloadManager下载*/ public class Ht ...

  3. 使用HttpURLConnection实现多线程下载

    HttpURLConnection继承了URLConnection,因此也可用于向指定网站发送GET请求.POST请求,而且它在URLConnection基础上提供了如下便捷方法: 实现多线程下载的步 ...

  4. java 多线程下载文件 以及URLConnection和HttpURLConnection的区别

    使用 HttpURLConnection 实现多线程下载文件 注意GET大写//http public class MultiThreadDownload { public static void m ...

  5. 【Java EE 学习 22 下】【单线程下载】【单线程断点下载】【多线程下载】

    一.文件下载简述 1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息 (1)response.setContentType("application/force-downl ...

  6. Java--使用多线程下载,断点续传技术原理(RandomAccessFile)

    一.基础知识 1.什么是线程?什么是进程?它们之间的关系? 可以参考之前的一篇文章:java核心知识点学习----并发和并行的区别,进程和线程的区别,如何创建线程和线程的四种状态,什么是线程计时器 简 ...

  7. android 多线程下载 断点续传

    来源:网易云课堂Android极客班第八次作业练习 练习内容: 多线程 asyncTask handler 多线程下载的原理 首先获取到目标文件的大小,然后在磁盘上申请一块空间用于保存目标文件,接着把 ...

  8. 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)

    1.smartimageview使用 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...

  9. Java 仿迅雷多线程下载

    package net.webjoy.jackluo.android_json; /** * 1.http Range "bytes="+ start+end * 2.Random ...

随机推荐

  1. 第一章 Django之web框架(1)

    Django 是新一代 Web 框架 中非常出色的成员.那么 Web 框架这个术语的确切含义到底是 什么呢? 要回答这个问题,让我们来看看通过编写标准的 CGI 程序来开发 Web 应用,这在大约19 ...

  2. kubernetes之pod生命周期,pod重启策略, 镜像拉取策略

    pod声明周期(状态):pending , running, succeeded, failed, unknown 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多 ...

  3. centos7下的/etc/rc.local自启动程序

    在centos6中有一个/etc/rc.local的启动文件,只要把需要经常启动的程序添加到此文件下并执行source /etc/rc.local就可以实现开机启动了. 在centos7中不知道也是如 ...

  4. kotlin命令行交互式终端

    之前在http://www.cnblogs.com/webor2006/p/7532982.htmlKotlin的环境搭建篇提到过在开发Kotlin可以用最原始的挖掘机式的命令行去编译运行,这里学习一 ...

  5. CF 976F 递增容量最大流

    给你一个二分图 要求你求出对于k=[0~Mindegree] 每个点的度数至少为k所需要的最少边数 并输出方案 如果是单个询问的话 直接跑一个下界网络流即可 但是有多个询问 重建图强行跑不行 反过来考 ...

  6. Linux的.a、.so和.o文件及链接时的命名

    在说明Linux的.a..so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系 windows下obj,lib,dll,exe的关系 lib是和dll对应的.lib是静 ...

  7. 2.PAT 1001 害死人不偿命的(3 n + 1 )猜想

    题目: 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 ( 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 ...

  8. python_tkinter组件

    1.按钮 # 按钮 # bg设置背景色 btn = tkinter.Button(root,text = '按钮',bg = 'red') btn.pack() # fg设置前景色(文字颜色) btn ...

  9. Java笔记(基础第一篇)

    一.初识java 1.Java是一种可以编写跨平台的.面向对象的程序设计语言. Java开发分成以下3个方向: (1). java SE:主要用于桌面程序的开发.是java EE和java ME的基础 ...

  10. c++中lambda表达式的用法

    #include <iostream> using namespace std; int main(){ ; auto func1 = [=](;}; auto func2 = [& ...