java多线程下载和断点续传
java多线程下载和断点续传,示例代码只实现了多线程,断点只做了介绍。但是实际测试结果不是很理想,不知道是哪里出了问题。所以贴上来请高手修正。
[Java]代码
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL; public class DownloadFile { /**
* @param args
*/
static int len;//线程平均下载文件长度
static int bn ;//每个线程写入文件的字节数
static int tn; //线程数
static String urlt;//下载地址
static String fileName;
static RandomAccessFile osf; //文件操作
public static void main(String[] args) {
// TODO Auto-generated method stub try {
urlt = "http://im.baidu.com/download/BaiduHi_4.2_Beta.exe";
fileName = "C:\\" + urlt.split("//")[1].split("/")[urlt.split("//")[1].split("/").length-1];
System.out.println(fileName);
URL url = new URL(urlt);
HttpURLConnection http = (HttpURLConnection) url.openConnection(); /**
* 此处设定5个线程下载一个文件tn = 5;
* 判断平均每个线程需下载文件长度:
*/
System.out.println("file size:" + http.getContentLength());
tn = 3;
len = http.getContentLength() / tn ;//舍去余数(余数自动舍去)计算每个线程应下载平均长度,最后一个线程再加上余数,则是整个文件的长度,
File f = new File(fileName);
if (f.exists()){
f.delete();
osf = new RandomAccessFile(f, "rw");
osf.seek(http.getContentLength()-1);
osf.write(0);
}else{
osf = new RandomAccessFile(f, "rw");
osf.seek(http.getContentLength()-1);
osf.write(0);
}
System.out.println("temp 文件长度:" + f.length());
Thread t;//下载子线程,
for (int j = 0; j < tn; j++) {
if(j == tn - 1){//如果最后一个线程则加上余数长度字节
bn = len + (http.getContentLength() % tn);
}else{
bn = len;
}
System.out.println("t"+ j + "线程下载长度:" + bn + "起始字节:" + len*j);
t = new DT(
j,
urlt,
fileName,
len*j,
bn );
t.start();
} } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date; public class DT extends Thread { String urlt;
int startl;
int end;
String fileName;
RandomAccessFile osf;
public DT(int i ,String url,String fileName,int start,int end){
this.setName("t"+i); //子线程名称
this.urlt = url; //下载地址
this.fileName = fileName;
this.startl = start; //子线程读取/写入起始字节
this.end = end;//子线程写入结束字节长度
}
public void run(){
try {
osf = new RandomAccessFile(fileName, "rw");
URL url = new URL(urlt);
HttpURLConnection http2 = (HttpURLConnection) url.openConnection();
http2.setRequestProperty("User-Agent","NetFox"); /*
* 断点续传和多线程下载的关键代码关键位置:即设置断点
* http2.setRequestProperty("RANGE", "bytes="+startl+"-");//设置断点位置,向服务器请求从文件的哪个字节开始读取。
* osf.seek(startl);//设置本地文件从哪个字节开始写入
* 如果是单线程,则首先要判断下载文件是否已经存在 及DownloadFile.java 里的 fileName = "C:\\eclipse.zip";
* 如果存在则开始断点续传,方法同多线程:
* 因为断点续传是从上次传输中断的字节开始,则首先要得到上次中断的位置,既是文件长度(针对单线程)f.length()
* 然后设置HTTP请求头属性RANGE,该属性告知服务器从哪个自己开始读取文件。
* 设置本地文件写入起始字节,及接从上次传输断点继续写入(断点续传)
* osf.seek(offset) 该方法设定从offset后一个字节开始写入文件
* 注意:多线程不能用文件长度做为写文件起始字节,需有配置文件记录上次读写的位置,迅雷下载既是使用该种方法。
*
*/
http2.setRequestProperty("RANGE", "bytes="+startl+"-");//设置断点位置,向服务器请求从文件的哪个字节开始读取。
osf.seek(startl);//设置本地文件从哪个字节开始写入 InputStream input = http2.getInputStream();
byte b[] = new byte[1024];//设置缓冲池,每次只读1024字节
Date d = new Date();//子线程开始下载时间
int l;//计算子线程读取和写入的文件长度,当长度大于每个子线程平均下载长度则终止线程
int i;
l = 0;
System.out.println(this.getName() + " 开始下载。。。");
while ( (i = input.read(b,0,1024)) != -1 && l < end){ //线程下载字节长度控制误差小于缓冲池大小,本示例为缓冲池1024字节
osf.write(b, 0, i);
b = new byte[1024];//重新赋值,避免重新读入旧内容
l += i;
}
Date d2 = new Date();//子线程结束下载时间
System.out.println(this.getName() + " 线程耗时: " + (d2.getTime() - d.getTime())/1000 + " 秒,实际共下载:" + l + "字节");//子线程下载耗时(秒)
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
http://outofmemory.cn/code-snippet/3888/java-many-xiancheng-xiazai-breakpoint-xuchuan
java多线程下载和断点续传的更多相关文章
- Java开发之多线程下载和断点续传
代码实现了多线程下载和断点续传功能 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream ...
- Android开发之多线程下载、断点续传、进度条和文本显示
代码实现了在Android环境下的多线程下载.断点续传.进度条显示和文本显示百分数: import java.io.BufferedReader; import java.io.File; impor ...
- JAVA多线程下载网络文件
JAVA多线程下载网络文件,开启多个线程,同时下载网络文件. 源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...
- Android学习记录(5)—在java中学习多线程下载之断点续传②
在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...
- Java多线程下载器FileDownloader(支持断点续传、代理等功能)
前言 在我的任务清单中,很早就有了一个文件下载器,但一直忙着没空去写.最近刚好放假,便抽了些时间完成了下文中的这个下载器. 介绍 同样的,还是先上效果图吧. Jar包地址位于 FileDownload ...
- java 多线程下载文件并实时计算下载百分比(断点续传)
多线程下载文件 多线程同时下载文件即:在同一时间内通过多个线程对同一个请求地址发起多个请求,将需要下载的数据分割成多个部分,同时下载,每个线程只负责下载其中的一部分,最后将每一个线程下载的部分组装起来 ...
- Android 多线程下载,断点续传,线程池
你可以在这里看到这个demo的源码: https://github.com/onlynight/MultiThreadDownloader 效果图 这张效果图是同时开启三个下载任务,限制下载线程数量的 ...
- java 多线程下载功能
import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; impo ...
- java 多线程下载文件 以及URLConnection和HttpURLConnection的区别
使用 HttpURLConnection 实现多线程下载文件 注意GET大写//http public class MultiThreadDownload { public static void m ...
随机推荐
- 关于Eclispe插件开发起步(一)
Eclipse中三个最吸引人的地方是: 第一是它创新性的图形API,就是SWT/JFace. 第二是它的插件机制. 第三个是利用它的插件机制开发众多功能强大的插件. 插件成就了Eclipse的今天.E ...
- GitHub 中国区前100 名技术专家
[本文是在一片新闻上摘录的,原地址为:http://mt.sohu.com/20160407/n443539407.shtml] 本文根据Github公开API,抓取了地址显示China的用户,根据粉 ...
- .NET学习笔记(4) — C#数据类型
目录 一:C#数据类型介绍 二:值类型和引用类型的区别和联系? 三:堆内存和栈内存? 四:参考资料 一:C#数据类型介绍 1:初识C#预定义数据类型 在C#的语言体系中,表示具体数据格式的规范 ...
- spark下统计单词频次
写了一个简单的语句,还没有优化: scala> sc. | textFile("/etc/profile"). | flatMap((s:String)=>s.spli ...
- lrzsz on linux
Linux Disibutaion:Ubuntu 16.04.1 LTS lrzsz是一款在linux里可代替ftp上传和下载的程序. 1.下载lrzsz源码包 #下载源码包 wget https:/ ...
- C/C++雷区之内存管理
C++雷区之内存管理 伟大的Bill Gates 曾经失言: 640K ought to be enough for everybody — Bill Gates 1981 程序员们经常编写内存管理程 ...
- HTML——<meta http-equiv="content-type" content="text/html; charset=UTF-8">
没有添加这句话的编码方式的话,很容易就乱码了 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&g ...
- iOS-Reachability的使用
// 下载地址:http://pan.baidu.com/s/1gd5NNDD // 1. 添加Reachability.h和Reachibility.m文件到项目中 // 2. 添加System ...
- C++中各种<string,T>关联方式的速度对比
把<string,T>(T为任意类型)关联起来,是很常见的需求.如笔者最近要做一个贝叶斯算法的垃圾邮件过滤器,就需要把每个单词与频率对应起来,做成一个表.而当单词很多时,对于每个单词做一遍 ...
- c# DataTable 中 Select 和 Clone 用法结合
C# DataTable是存放数据的一个离线数据库,将数据一下加载到内存. DataTable.Select ()方法: Select();//全部查出来 Select(过滤条件);//根据过滤 ...