为了更快的下载资源,我们可以采用多线程的方式来实现文件的下载。
多线程文件下载的基本原理如下:使用HttpURLConnection获取与资源指定URL的链接,httpurlconnection对象通过getContentLength可以获取下载文件的长度,等到需要下载的文件的长度以后,在本地创建一个与下载文件长度相同的文件,然后通过RandomAccessFile对文件进行写入操作,那么如何加入多线程呢?思想是将文件分为几个部分,每一个线程完成每一个部分的下载和文件写入操作。通过RandomAccessFile可以实现文件的随机访问,因此每个线程都可以讲自己负责下载的内容写到文件中指定的位置,而不用担心文件中内容出现错位。
下面是线程类的代码
public class MulThreadDownLoad extends Thread {
private String path;
private File file;
private int tasksize;
private int threadid;
public MulThreadDownLoad(String path ,File file , int tasksize, int threadid){
this.path = path; //文件路径
this.file = file; //文件
this.tasksize = tasksize; //单个线程的下载量
this.threadid = threadid; //线程的id
}
@Override
public void run() {
try {
int startPoint = threadid * tasksize; //每条线程写入文件的起点
int endPoint = (threadid + 1 ) * tasksize -1 ; //每条线程写入文件的终点
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd");
accessFile.seek(startPoint);
HttpURLConnection con = (HttpURLConnection) new URL(path).openConnection();
con.setConnectTimeout(500);
con.setRequestMethod("GET");
// con.setRequestProperty("Range", "bytes="+startPoint+"-"+endPoint); 如果设置了Range字段,那么响应码是206而不是200
if(con.getResponseCode() == 200){
InputStream ins = con.getInputStream();
ins.skip(startPoint); //跳过前面线程已经下载过的内容,
byte [] buffer = new byte [1024];
int length = 0;
while((length = ins.read(buffer)) != -1 ){ //将读取的字节写入文件中
accessFile.write(buffer);
}
accessFile.close();
ins.close();
}
System.out.print((threadid +1 )+"线程已经下载完成 :");
System.out.println("bytes = "+startPoint+"-"+endPoint);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
下面这个是测试类,在测试类中,指定了文件下载的路径,通过文件的路径,获取了文件名
public class MulThreadDownLoadTest {
private File file ;
public static void main(String args []) throws Exception{
String path = "http://localhost:8080/test/jj.jpg";
new MulThreadDownLoadTest().download(path,3);
}
/*
* @path 指定下载的目标路径
* @threaCount 指定需要多少个线程进行下载
*/
public void download(String path, int threadCount ) throws Exception{
URL url = new URL(path);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(500);
if(con.getResponseCode() == 200){
int ContentLength = con.getContentLength();//获取响应的长度
String fileName = getFileName(path); //获取文件名
file = new File(fileName);
System.out.println("下载文件大小"+ContentLength);
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd"); //rwd 表示对文件内容的每个更新都同步写入到底层存储设备。
accessFile.setLength(ContentLength);
accessFile.close();
//计算每个线程的下载长度为多少
int tasksize = (ContentLength%threadCount == 0 ? ContentLength/threadCount : ContentLength/threadCount+ 1);
for(int threadid = 0; threadid < threadCount ;threadid++ ){
new MulThreadDownLoad(path,file,tasksize,threadid).start();
}
}
}
public static String getFileName(String path){
return path.substring(path.lastIndexOf("/")+1);
}
}
文章参考
传智播客培训视频
http://www.cnblogs.com/tiantianbyconan/archive/2013/02/20/2919132.html
分享到:
相关推荐
实现一个能够从网上下载文件的功能,需要多线程来实现。 下载的传输协议采用socket或者http及ftp协议
Socket实现文件上传下载,包含服务器和客户端实现,服务店采用多线程实现
采用apache commons开发包,实现了FTP多线程下载,并有简单的包括进度条的界面,代码的运行:1 把自己的PC配置成FTP服务器(只需下载Serc-U软件)2 建立用户,用户名:zhangyu,密码:123,设置根目录,并拷贝进一些...
该程序采用多线程的方式实现文件上传服务器,此实例已经本人测试通过。
用C#实现的多线程多任务下载,采用文件切块,多线程分块下载,再拼接
其主要原因是这些软件都采用了多线程下载和断点续传技术。如果我们自己来编写一个类似这样的程序,也能够快速的在互联网上下载文件,那一定是非常愉快的事情。下面我就讲一讲如何利用C#语言编写一个支持多线程下载...
采用Visual C++ 6.0开发的一个TCP文件传输系统,采用多线程的传输方式,支持断点续传,利用配置文件设置基本的初始化信息。 文件包括源代码和安装包,源代码里包括自定义的文件传输通信协议。 程序采用分层的设计...
多线程socket文件传输_支持断点续传_收发消息_点对多点
采用多个线程下载文件等。利用多线程的下载原理,实现了一个简单的android应用程序下载文件。
采用多线程分发的方式,实现对电脑1-65535端口进行扫描,并把开启的端口,记录到结果文件中去
程序采用了DES的方式进行文件的加解密。 并采用多线程技术准确的将文件加解密进度显示在进度条上,使用构造函数实现各窗口间的参数传递!
多线程上传多文件,线程数可以自行确定,可以上传整个目录树,采用的是WinInet编程技术。
采用I/O复用技术select实现socket通信,采用多线程负责每个客户操作处理,完成Linux下的多客户聊天室! OS:Ubuntu 15.04 IDE:vim gcc make DB:Sqlite 3 Time:2015-12-09 ~ 2012-12-21 项目功能架构: 1. ...
一个线程委托库的实现源码,最大的优点是实现多线程不再困难,线程同步和管理不再头疼,同时内置了浏览器线程的实现。 线程委托的概念主要是在任意线程中委托其他线程执行代码,例如调用一个API函数,或者调用一个...
本程序为在VC++6.0下编写的MFC文档应用程序,实现多线程下载功能,支持HTTP和FTP协议、断点续传,采用WinSock编程接口。(掩耳下载,非上传者原创)
代码经过压力测试,采用反应器模式,没有第三方框架,实现功能:可以一个线程处理多个请求,也可以加上多线程。处理数据采用的多线程。实现功能:基于HTTP协议,解析请求和拼接响应,基于NIO的非阻塞,线程池,文件...
poll:和select几乎没有区别,区别在于文件描述符的存储方式不同,poll采用链表的方式存储,没有最大存储数量的限制; epollepoll底层通过红黑树来描述,并维护一个ready list,将事件表中已经就绪的事件添加到这里...
Http多线程下载模块,采用了文件内存映射等技术.本人是在vs2010 + qt5下实现。 qt4下我简单的写了下字符集的处理(未测试),可能会乱码.(qt5和qt4的差别还是有些大,可能要做些小的修改),程序不复杂,不算多,...
一个基于C#与多线程技术实现的文件管理系统程序代码,采用VS2005+C#开发完成。
模拟银行取号,服务,结束服务的过程,用户到银行后先取号排队等待,然后银行的各个窗口开始叫号,整个ap采用多线程方法,使用VS2005(VC)开发,包含完整的声音文件