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多线程下载和断点续传的更多相关文章

  1. Java开发之多线程下载和断点续传

    代码实现了多线程下载和断点续传功能 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream ...

  2. Android开发之多线程下载、断点续传、进度条和文本显示

    代码实现了在Android环境下的多线程下载.断点续传.进度条显示和文本显示百分数: import java.io.BufferedReader; import java.io.File; impor ...

  3. JAVA多线程下载网络文件

    JAVA多线程下载网络文件,开启多个线程,同时下载网络文件.   源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...

  4. Android学习记录(5)—在java中学习多线程下载之断点续传②

    在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...

  5. Java多线程下载器FileDownloader(支持断点续传、代理等功能)

    前言 在我的任务清单中,很早就有了一个文件下载器,但一直忙着没空去写.最近刚好放假,便抽了些时间完成了下文中的这个下载器. 介绍 同样的,还是先上效果图吧. Jar包地址位于 FileDownload ...

  6. java 多线程下载文件并实时计算下载百分比(断点续传)

    多线程下载文件 多线程同时下载文件即:在同一时间内通过多个线程对同一个请求地址发起多个请求,将需要下载的数据分割成多个部分,同时下载,每个线程只负责下载其中的一部分,最后将每一个线程下载的部分组装起来 ...

  7. Android 多线程下载,断点续传,线程池

    你可以在这里看到这个demo的源码: https://github.com/onlynight/MultiThreadDownloader 效果图 这张效果图是同时开启三个下载任务,限制下载线程数量的 ...

  8. java 多线程下载功能

    import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; impo ...

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

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

随机推荐

  1. 210 - Concurrency Simulator(WF1991, deque, 模拟)

    题目有点长,理解题花了不少时间 粘下别人的翻译~ 你的任务是模拟n个程序(按输入顺序编号为1~n)的并行执行.每个程序包含不超过25条语句,格式一共有5种: var=constant(赋值): pri ...

  2. Spring 事务模型

    一.三种事务模型 1.本地事务模型:开发人员不用知道事务的存在,事务全部交给数据库来管理,数据库自己决定什么时候提交或回滚,所以数据库是事务的管理者. Connection conn=jdbcDao. ...

  3. js动态生成按钮,页面用DIV简单布局

    今天朋友让我忙帮给写个页面,由于时间紧破,所以没有完善,暂时先贴出来,以后有时间了在做修改 <!DOCTYPE html><html><head><title ...

  4. SQLserver中常用的函数及实例

    聚合函数 as是可以起别名的,在select和from之间的是表示列名,可以不加单引号)(聚合函数中的count不仅能对数字进行操作还能对字符型进行操作,其余的只能对数字操作) 最小值 select  ...

  5. plsql导入导出表

    原来总是直接 tools->import talbes->Oracle Import结果发现有的时候会出错:有的表不能正确导入, baidu+googel解决办法如下: 导出步骤: 1 t ...

  6. JAVA访问配置文件总结

    一.全局配置的简单 propertie 文件实现 package com.testgs.utils; import java.util.*; import java.io.*; public fina ...

  7. Appium Python Driver Api

  8. 工作“触雷”经历与总结--记博弈论的应用

    工作三年,职场受挫.一些值得说或者不值得说的事情,也懒得去记录.无奈,更多时无奈.内心的骄傲或者自负也不值得炫耀.天生骄傲,或者也只是自身内心的呐喊.毕竟,骄傲的人也不会说出来,搞的好像是有点似得. ...

  9. C#基于AE组件二次开发常见问题

    由于本人从事的是在.net平台下进行GIS的二次开发,所以第一篇博文就说一下:我最近在项目中出现的常见的问题,如果能够给大家增加一点点便利,也是我的荣幸,如果大家对于这次博文有什么意见和建议,欢迎大家 ...

  10. 对比MySQL,什么场景MongoDB更适用

    原文链接: http://page.factj.com/blog/p/4078 MongoDB已经流行了很长一段时间,相对于MySQL,究竟什么场景更需要用MongoDB?下面是一些总结. 更高的写入 ...