【转自】

光仔December

http://blog.csdn.net/acmman

问题:多线程下载的好处?

多线程下载比单线程下载快,主要的原因是采用多线程下载,可以抢占更多的服务器资源。抢占Cpu的处理空间,实现更快的下载速度

问题:多线程下载位置的确定?

开启N条线程下载文件,假设文件大小为buf,那么每条线程的下载量为:
buf%N==0?buf/N:buf/N+1;

那么,每一条线程应该从网络文件的什么位置开始下载??

假设线程id号threadid为0,1,2,每一条线程下载的数据量为block=4

第一个文件从threadid*block开始下载,结束位置(threadid+1)*block-1

所以公式为:
int start=threadid*block;
int end=(threadid+1)*block-1;

多线程下载源码(仅供参考)

  1. package cn.deu.hpu.download;
  2. import java.io.File;
  3. import java.io.InputStream;
  4. import java.io.RandomAccessFile;
  5. import java.net.HttpURLConnection;
  6. import java.net.URL;
  7. public class MulThreadDownLoad {
  8. public static void main(String[] args) throws Exception{
  9. String path="http://192.168.111.104:8080/web/gg.jpg";
  10. new MulThreadDownLoad().download(path,3);
  11. }
  12. /*下载文件
  13. * path 网络文件路径
  14. * */
  15. public void download(String path,int threadsize)throws Exception{
  16. URL url=new URL(path);
  17. HttpURLConnection conn=(HttpURLConnection) url.openConnection();
  18. conn.setConnectTimeout(5000);
  19. conn.setRequestMethod("GET");
  20. if(conn.getResponseCode()==200){
  21. //取得网络文件的长度
  22. int length=conn.getContentLength();
  23. File file=new File(getFilename(path));
  24. //随机访问文件类(生成一个与网络文件长度相等的本地文件)
  25. RandomAccessFile accessFile=new RandomAccessFile(file, "rwd");
  26. accessFile.setLength(length);
  27. accessFile.close();
  28. //计算每条线程需要下载的数据量
  29. int block=length%threadsize==0?length/threadsize:length/threadsize+1;
  30. for (int threadid = 0; threadid< threadsize; threadid++) {
  31. new DownloadThread(threadid,block,url,file).start();
  32. }
  33. }else{
  34. System.out.println("下载失败!");
  35. }
  36. }
  37. private String getFilename(String path) {
  38. //从URL地址的最后一个"/"后开始记录文件名
  39. return path.substring(path.lastIndexOf("/")+1);
  40. }
  41. private class DownloadThread extends Thread{
  42. private int threadid;
  43. private int block;
  44. private URL url;
  45. private File file;
  46. public DownloadThread(int threadid,int block,URL url,File file){
  47. this.threadid=threadid;
  48. this.block=block;
  49. this.url=url;
  50. this.file=file;
  51. }
  52. public void run(){
  53. //计算该线程从网络文件的什么位置开始下载
  54. int start=threadid*block;
  55. //下载到网络文件的什么位置结束
  56. int end=(threadid+1)*block-1;
  57. try {
  58. RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
  59. //从某一个位置开始写入数据
  60. accessFile.seek(start);
  61. HttpURLConnection conn=(HttpURLConnection) url.openConnection();
  62. conn.setConnectTimeout(5000);
  63. conn.setRequestMethod("GET");
  64. //指定行网络文件的某个区域下载数据(开始位置-结束位置)
  65. conn.setRequestProperty("Range", "bytes="+start+"-"+end);
  66. //请求某一段数据的话,请求码不是200,是206
  67. if(conn.getResponseCode()==206){
  68. InputStream instream=conn.getInputStream();
  69. byte [] buffer=new byte[1024];
  70. int len=0;
  71. while((len=instream.read(buffer))!=-1){
  72. accessFile.write(buffer,0,len);
  73. }
  74. accessFile.close();
  75. instream.close();
  76. }
  77. System.out.println("第"+(threadid+1)+"线程已经下载完成");
  78. } catch (Exception e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. }
  83. }
package cn.deu.hpu.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL; public class MulThreadDownLoad { public static void main(String[] args) throws Exception{
String path="http://192.168.111.104:8080/web/gg.jpg";
new MulThreadDownLoad().download(path,3);
} /*下载文件
* path 网络文件路径
* */
public void download(String path,int threadsize)throws Exception{
URL url=new URL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode()==200){
//取得网络文件的长度
int length=conn.getContentLength();
File file=new File(getFilename(path));
//随机访问文件类(生成一个与网络文件长度相等的本地文件)
RandomAccessFile accessFile=new RandomAccessFile(file, "rwd");
accessFile.setLength(length);
accessFile.close(); //计算每条线程需要下载的数据量
int block=length%threadsize==0?length/threadsize:length/threadsize+1;
for (int threadid = 0; threadid< threadsize; threadid++) {
new DownloadThread(threadid,block,url,file).start();
}
}else{
System.out.println("下载失败!");
} } private String getFilename(String path) {
//从URL地址的最后一个"/"后开始记录文件名
return path.substring(path.lastIndexOf("/")+1);
} private class DownloadThread extends Thread{
private int threadid;
private int block;
private URL url;
private File file;
public DownloadThread(int threadid,int block,URL url,File file){
this.threadid=threadid;
this.block=block;
this.url=url;
this.file=file;
} public void run(){
//计算该线程从网络文件的什么位置开始下载
int start=threadid*block;
//下载到网络文件的什么位置结束
int end=(threadid+1)*block-1;
try {
RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
//从某一个位置开始写入数据
accessFile.seek(start);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//指定行网络文件的某个区域下载数据(开始位置-结束位置)
conn.setRequestProperty("Range", "bytes="+start+"-"+end);
//请求某一段数据的话,请求码不是200,是206
if(conn.getResponseCode()==206){
InputStream instream=conn.getInputStream();
byte [] buffer=new byte[1024];
int len=0;
while((len=instream.read(buffer))!=-1){
accessFile.write(buffer,0,len);
}
accessFile.close();
instream.close();
}
System.out.println("第"+(threadid+1)+"线程已经下载完成");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

转载请注明出处!程序猿之洞:http://blog.csdn.net/acmman

【转】【JAVA应用】多线程断点下载的更多相关文章

  1. Java实现多线程断点下载(下载过程中可以暂停)

    线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...

  2. Java之多线程断点下载的实现

    RandomAccessFile类: 此类的实例支持对随机訪问文件的读取和写入.随机訪问文件的行为相似存储在文件系统中的一个大型 byte 数组. 存在指向该隐含数组.光标或索引,称为文件指针.输入操 ...

  3. Android(java)学习笔记216:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1.新建一个Android工程: (1)其中我们先实现布局 ...

  4. Android(java)学习笔记159:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1. 新建一个Android工程: (1)其中我们先实现布 ...

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

    原文:http://www.open-open.com/lib/view/open1423214229232.html 其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载 ...

  6. andoid 多线程断点下载

    本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多 ...

  7. 我的Android进阶之旅------>Android基于HTTP协议的多线程断点下载器的实现

    一.首先写这篇文章之前,要了解实现该Android多线程断点下载器的几个知识点 1.多线程下载的原理,如下图所示 注意:由于Android移动设备和PC机的处理器还是不能相比,所以开辟的子线程建议不要 ...

  8. iOS开发网络篇—大文件的多线程断点下载

    http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...

  9. iOS开发网络请求——大文件的多线程断点下载

    iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...

  10. iOS开发网络篇—大文件的多线程断点下载(转)

    http://www.cnblogs.com/wendingding/p/3947550.html   iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了 ...

随机推荐

  1. swiper使用小结

    最近做一个移动端项目想用Swiper移动端插件,需求实现一个轮播图的效果,并且需要自定义分页器,效果跟这个差不多这里demo 好吧,开始动手! 注意参考的3.0Swiper的API文档需要引入3.0版 ...

  2. PHP简洁之道

    前言 前几天在GitHub看到一篇写PHP简洁之道的译文,觉得还不错,所以转在了自己的博客中,只不过有一些地方好像没有翻译,再加上排版上的一些小问题,所以决定自己翻译一遍. 原文地址:https:// ...

  3. JavaScript OOP 之 this指向

    今天给大家分享一个JavaScript OOP中关于分辨this指向对象的小技巧,很实用呦! 我们先来看一段代码: 大家能判断出func();和obj.func();这两句的this指向吗? 首先,我 ...

  4. python 使用标准库根据进程名获取进程的pid

    有时候需要获取进程的pid,但又无法使用第三方库的时候. 方法适用linux平台. 方法1 使用subprocess 的check_output函数执行pidof命令 from subprocess ...

  5. 编程&blog处女篇-用C#求100以内的质数

    using System;namespace Loops{ class Program { static void Main(string[] args) { /*局部变量定义*/ int i, j; ...

  6. Linux系列教程(十)——Linux文本编辑器vim

    通过前面几篇博客我们终于结束了Linux常用命令的介绍,Linux常用命令主要包括以下: ①.Linux文件和目录处理命令 ②.Linux链接命令和权限管理命令 ③.Linux文件搜索命令 ④.Lin ...

  7. python爬虫如何入门

    学爬虫是循序渐进的过程,作为零基础小白,大体上可分为三个阶段,第一阶段是入门,掌握必备的基础知识,第二阶段是模仿,跟着别人的爬虫代码学,弄懂每一行代码,第三阶段是自己动手,这个阶段你开始有自己的解题思 ...

  8. 链表倒数第n个节点

    找到单链表倒数第n个节点,保证链表中节点的最少数量为n. 样例 给出链表 3->2->1->5->null和n = 2,返回倒数第二个节点的值1. /** * Definiti ...

  9. IdentityServer4 实现自定义 GrantType 授权模式

    OAuth 2.0 默认四种授权模式(GrantType): 授权码模式(authorization_code) 简化模式(implicit) 密码模式(password) 客户端模式(client_ ...

  10. sass学习--安装ruby

    1.下载ruby:https://rubyinstaller.org/downloads/ 2.安装完ruby之后,在开始菜单中,找到刚才我们安装的ruby,打开Start Command Promp ...