java多线程下载代码_「java多线程」JAVA代码实现多线程下载 - seo实验室

java多线程

首先,我们构建一个多线程下载工具类--DownUtil.代码如下:import java.net.URL;

import java.net.HttpURLConnection;

import java.io.InputStream ;

import java.io.RandomAccessFile;

public class DownUtil

{

//定义下载资源的路径

private String path;

//指定所下载的文件的保存位置

private String targetFile;

//定义需要使用多少个线程下载资源

private int threadNum;

//定义下载的线程对象

private DownThread[] threads;

//定义下载的文件的总大小

private int fileSize;

//构造器

public DownUtil(String path,String targetFile,int threadNum)

{

this.path=path;

this.threadNum=threadNum;

//初始化threads数组

threads=new DownThread[threadNum];

this.targetFile=targetFile;

}

public void download() throws Exception

{

URL url=new URL(path);

//1.通过调用URL对象的openConnection()方法来创建URLConnection对象

HttpURLConnection conn=(HttpURLConnection)url.openConnection();

//2.设置URLConnection的参数和普通请求属性

conn.setConnectTimeout(5*1000);

conn.setrequestMethod("GET");

conn.setrequestproperty(

"Accept",

"image/gif,image/jpeg,image/pjpeg,image/pjpeg,"

+"APPlication/x-shockwave-flash,application/xaml+xml,"

+"application/vnd.ms-xpsdocument,application/x-ms-xbap,"

+"application/x-ms-application,application/vnd.ms-excel,"

+"application/vnd.ms-powerpoint,application/msword,*/*");

conn.setRequestProperty("Accept-Language","zh-CN");

conn.setRequestProperty("Charset","UTF-8");

conn.setRequestProperty("Connection","Keep-Alive");

//得到文件大小

fileSize=conn.getcontentLength();

conn.disconnect();

int currentPartSize=fileSize/threadNum+1;

RandomAccessFile file=new RandomAccessFile(targetFile,"rw");

//设置本地文件的大小

file.setLength(fileSize);

file.close();

for(int i=0;i

{

//计算每个线程下载开始的位置

int startPos=i*currentPartSize;

//每个线程使用一个RandomAccessFile进行下载

RandomAccessFile currentPart=new RandomAccessFile(targetFile,"rw");

//定位该线程的下载位置

currentPart.seek(startPos);

//创建下载线程

threads[i]=new DownThread(startPos,currentPartSize,currentPart);

//启动下载线程

threads[i].start();

}

}

//获取下载的完成百分比

public double getCompleteRate()

{

//统计多个线程已经下载的总大小

int sumSize=0;

for(int i=0;i

{

sumSize+=threads[i].length;

}

//返回已经完成的百分比

return sumSize*1.0/fileSize;

}

public class DownThread extends Thread

{

//当前线程的下载位置

private int startPos;

//定义当前线程负责下载的文件大小

private int currentPartSize;

//当前线程需要下载的文件块

private RandomAccessFile currentPart;

//定义该线程已下载的字节数

public int length;

//构造器

public DownThread(int startPos,int currentPartSize,RandomAccessFile currentPart)

{

this.startPos=startPos;

this.currentPartSize=currentPartSize;

this.currentPart=currentPart;

}

//下载线程的主函数体

public void run()

{

try

{

URL url=new URL(path);

//1.通过调用URL对象的openConnection()方法来创建URLConnection对象

HttpURLConnection conn=(HttpURLConnection)url.openConnection();

//2.设置URLConnection的参数和普通请求属性

conn.setConnectTimeout(5*1000);

conn.setRequestMethod("GET");

conn.setRequestProperty(

"Accept",

"image/gif,image/jpeg,image/pjpeg,image/pjpeg,"

+"application/x-shockwave-flash,application/xaml+xml,"

+"application/vnd.ms-xpsdocument,application/x-ms-xbap,"

+"application/x-ms-application,application/vnd.ms-excel,"

+"application/vnd.ms-powerpoint,application/msword,*/*");

conn.setRequestProperty("Accept-Language","zh-CN");

conn.setRequestProperty("Charset","UTF-8");

//4.远程资源变为可用,程序可以通过输入流读取远程资源的数据

InputStream inStream=conn.getInputStream();

//跳过stratPos个字节,表明该线程只下载自己负责的那部分文件

//同时每个线程都会在指定的文件区域写入,所以不会因为多线程而出

//现资源组合的错乱,从指定位置读取资源,写入到指定位置

inStream.skip(this.startPos);

byte[] buffer=new byte[1024];//自己设置一个缓冲区

int hasread=0;

//-----------------读取网路数据,并写入本地文件-------------------

//inStream.read(buffer))==-1 表示读取到文件末尾

while(length

{

currentPart.write(buffer,0,hasread);

//累计该线程下载的总大小

length+=hasread;

//System.out.println(getName()+" "+hasread);

}

//System.out.println(getName()+" length "+length+" currentPartSize "+currentPartSize);

//即使length>currentPartSize会是的该线程多写入几个字节,

//但是下一个线程会从文件的指定位置写入,就会覆盖掉之前线程多写的一部分内容

currentPart.close();

inStream.close();

}

catch (Exception e)

{

e.printstacktrace();

}

}

}

}

上面代码的大致思路如下:

DownUtils类—启动、实现多线程下载的类;

DownThread—线程下载类,作为DownUtils类的辅助类,主要实现单个线程的下载逻辑。

程序中DownUtils类中的download()方法负责按如下步骤实现多线程下载

创建URL对象

获取指定URL对象所指向资源的大小(通过getConnectLength()方法获得),此处,用到了URLConnection类,该类代表Java应用程序和URL之间的通信链接。

在本地磁盘上创建一个与网络资源具有同样大小的空文件

计算每个线程应该下载网络资源的哪个部分

依次创建、启动多个线程来下载网络资源的指定部分

创建一个和URL的连接,并发送请求、读取此URL引用的资源需要如下几个步骤:

通过调用URL对象的openConnection()方法来创建URLConnection对象;

设置URLConnection的参数和普通请求属性;

如果只是发送GET方式请求,则使用connect()方法建立和远程资源之间的实际连接即可;如果需要发送POST方式的请求,则需要获取URLConnection实例对应的输出流来发送请求参数

远程资源变为可用,程序可以访问远程资源的头字段或通过输入流读取远程资源的数据

测试函数如下:

public class MultiThreadDown

{

public static void main(String[] args)

throws Exception

{

//初始化DownUtil对象

final DownUtil downUtil=new DownUtil("http://img10.360buyimg.com/n0/jfs"+

"/t18166/359/202833592/24066/9da49/5a628ffeN32d2b7c8.jpg","iOS.png",4);

//开始下载

downUtil.download();

new Thread(()->

{

while(downUtil.getCompleteRate()<1)

{

//每隔0.1秒查询一次任务的完成进度

//GUI程序中可根据该进度来绘制进度条

System.out.println("已完成:"+downUtil.getCompleteRate());

try

{

Thread.sleep(100);

}

catch (Exception ex){}

}

}).start();

}

}

相关阅读

java stringbuilder 清空问题

我也是碰到了这个问题才开始研究的,网上答案偏多,并且时间范围也比较大,各个版本的java 优化也不清楚

https://blog.csdn.net/iblade/article/details/80749148

首先右击【计算机】进入【属性】然后选择其中的【高级系统设置】

点击进入【高级】中的【环境变量】,进入环境变量编辑界面。

在下

java中用于控制可见性的4个访问修饰符

private————仅对本类可见

public————对该项目中所有类可见

protected————对

经测试,本方法在windows环境下安装的tomcat是起作用的。在java项目中设置自定义变量的方法有很多种,如果你项目中使用 System.getP

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.得到服务下载文件的大小,然后在本地设置一个临时文件和服务端文件大小一致 a)获得访问网络地址 b)通过URL对象的openConnection()方法打开连接,返回一个连接对象 c)设置请求头 i.setRequestMethod ii.setConnectTimeout iii.setReadTimeout d)判断是否响应成功 e)获取文件长度(getContentLength()) f)随机访问文件的读取与写入RandomAccessFile(file, mode) g)设置临时文件与服务文件大小一致(setLength()) h)关闭临时文件 2.计算出每个线程下载的大小(开始位置,结束位置) a)计算出每个线程下载的大小 b)for循环,计算出每个线程的开始、结束位置 c)最后一个线程处理 3.每创建好一次就要开启线程下载 a)构造方法 b)通过URL对象的openConnection()方法打开连接,返回一个连接对象 c)设置请求头 i.setRequestMethod ii.setConnectTimeout d)判断是否响应成功(206) e)获取每个线程返回的流对象 f)随机访问文件的读取与写入RandomAccessFile(file, mode) g)指定开始位置 h)循环读取 i.保存每个线程下载位置 ii.记录每次下载位置 iii.关闭临时记录位置文件 iv.随机本地文件写入 v.记录已下载大小 i)关闭临时文件 j)关闭输入流 4.为了杀死线程还能继续下载的情况下,从本地文件上读取已经下载文件的开始位置 a)创建保存记录结束位置的文件 b)读取文件 c)将流转换为字符 d)获取记录位置 e)把记录位置赋给开始位置 5.当你的n个线程都下载完毕的时候我进行删除记录下载位置的缓存文件 a)线程下载完就减去 b)当没有正在运行的线程时切文件存在时删除文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值