(1)
public class MultiThreadDownload extends Thread {
//定义的一些常量变量,看名字就知道什么意思了
private static final int BUFFER_SIZE = 1024;
private int blockSize;
private int threadNum = 5;
private int fileSize;
private int downloadedSize;
String urlStr, threadNo, fileName;
private String savePath;
private int downloadPercent = 0 , downloadSpeed = 0, usedTime=0;
private long startTime,curTime;
private boolean completed = false;
//用URL,保存路径,保存名称来构造。
public MultiThreadDownload(String URL, String savePath, String fileName) {
this.urlStr = URL;
this.savePath = savePath;
this.fileName = fileName;
}
@Override
public void run() {
FileDownloadThread[] fds = new FileDownloadThread[threadNum];
try {
URL url = new URL(urlStr);
URLConnection conn = url.openConnection();
fileSize = conn.getContentLength();
blockSize = fileSize / threadNum;
File file[] = new File[threadNum];
//根据默认的线程数,或者自己修改设置的线程数来分块,创建分块后的文件块
for (int i = 0; i < threadNum; i++) {
file[i] = new File(savePath + fileName + ".part"
+ String.valueOf(i));
//将分块的文件交给每个线程处理,最后一块应该大于等于平均块,因为可能有余数
FileDownloadThread fdt = new FileDownloadThread(url, file[i], i
* blockSize, (i + 1) != threadNum ? ((i + 1)
* blockSize - 1) : fileSize);
fdt.setName("Thread" + i);
fdt.start();
fds[i] = fdt;
}
startTime = System.currentTimeMillis();
//获取起始下载的时间,用次来计算速度。
boolean finished = false;
while (!finished) {
downloadedSize = 0;
finished = true;
for (int i = 0; i < fds.length; i++) {
downloadedSize += fds[i].getDownloadSize();
if (!fds[i].isFinished()) {
finished = false;
}
}
//计算下载的百分比
downloadPercent = (downloadedSize*100)/fileSize;
//获取当前时间,计算平均下载速度
curTime = System.currentTimeMillis();
usedTime =(int)((curTime-startTime)/1000);
if(usedTime==0)
usedTime =1;
downloadSpeed = (downloadedSize/usedTime)/1024;
sleep(1000);
}
//这个是分块下载完成的标志
completed = true;
//进行模块整合
RandomAccessFile raf = new RandomAccessFile(savePath + fileName,
"rw");
byte[] tempbytes = new byte[BUFFER_SIZE];
InputStream in = null;
int byteread = 0;
for (int i = 0; i < threadNum; i++) {
in = new FileInputStream(file[i]);
while ((byteread = in.read(tempbytes)) != -1)
{
raf.write(tempbytes, 0, byteread);
}
//每次整合完一块就删除一块。
in.close();
file[i].delete();
}
raf.close();
System.out.println(getName() + " end");
} catch (Exception e) {
// TODO: handle exception
}
}
//获取下载百分比
public int getDownloadPercent(){
return this.downloadPercent;
}
//获取下载速度
public int getDownloadSpeed(){
return this.downloadSpeed;
}
//修改默认线程数
public void setThreadNum(int threadNum){
this.threadNum = threadNum;
}
//分块下载完成的标志
public boolean isCompleted(){
return this.completed;
}
}
(2)
public class FileDownloadThread extends Thread {
private static final int BUFFER_SIZE = 1024;
private URL url;
private File file;
private int startPosition;
private int endPosition;
private int curPosition;
private boolean finished = false;
private int downloadSize = 0;
//分块构造函数
public FileDownloadThread(URL url, File file, int startPosition,
int endPosition) {
this.url = url;
this.file = file;
this.startPosition = startPosition;
this.curPosition = startPosition;
this.endPosition = endPosition;
}
public void run() {
BufferedInputStream bis = null;
RandomAccessFile fos = null;
byte[] buf = new byte[BUFFER_SIZE];
URLConnection con = null;
try {
//打开URL连接
con = url.openConnection();
con.setAllowUserInteraction(true);
//判断是否该文件存在,如果存在且下载完成,直接返回。
if ((file.length() + startPosition) == endPosition) {
this.finished = true;
}
//文件未下载完成,获取到当前指针位置,继续下载。
else {
con.setRequestProperty("Range", "bytes="
+ (startPosition + file.length()) + "-" + endPosition);
fos = new RandomAccessFile(file, "rw");
fos.seek(file.length());
bis = new BufferedInputStream(con.getInputStream());
while (curPosition < endPosition) {
int len = bis.read(buf, 0, BUFFER_SIZE);
if (len == -1) {
break;
}
fos.write(buf, 0, len);
curPosition = curPosition + len;
if (curPosition > endPosition) {
downloadSize += len - (curPosition - endPosition) + 1;
} else {
downloadSize += len;
}
}
this.finished = true;
bis.close();
fos.close();
}
} catch (IOException e) {
System.out.println(getName() + " Error:" + e.getMessage());
}
}
public boolean isFinished() {
return finished;
}
public int getDownloadSize() {
return downloadSize;
}
}
(3)DownActivity
public class DownActivity extends Activity {
private String url="http://download.eoemarket.com/app?id=9449&client_id=114&channel_id=115";
private String savepath="/sdcard/";
private String savename="downfile.apk";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
MultiThreadDownload down=new MultiThreadDownload(url,savepath,savename);
down.start();
}
}
分享到:
相关推荐
新鲜出炉的SpringBoot版本的多线程下载文件,可以拿来整合SpringBoot项目或者SSM项目,可直接运行测试!!!
可以多线程下载文件c++的客户端软件,可以切割文件并传输
C#实现多线程下载文件,结合多线程技术的各方面知识,是比较好的学习例子。
java实现多线程下载文件功能,通过线程池管理,实现下载文件速度快,安全。
qt多线程下载文件的Demo,支持http协议,支持多任务下载
Android多线程下载文件,支持断点续传,这里用的数据库存储
C# 多线程下载文件 下载即可运行 vs05.
Android多线程下载文件实例 Android多线程下载文件实例
C#多线程下载文件源码测试通过,而且值得参考,源码易懂易用适合二次开发
Android多线程断点续传下载器,很好的学习资料,包括完整代码以及详细注释。 无须其他配置,在网上找一个mp3下载地址(我找的是百度音乐)放到strings.xml不报错就行。
htp多线程断点下载文件 线程数量并不代表下载的速度喔。
这是一个在listview或gridview中选项同时分别下载文件的demo。 每个选项进度条分别更新进度。
VB带进度条动画的多线程下载文件源码,一款可以多线程下载的小程序,下载过程中适时显示进度条,并且本多线程下载程序是4线程同步下载,真正的多线程下载。使用说明:一款可以加快下载文件速度的绿色小程序,有了它...
写一个多线程分块下载文件工具。网上的一些代码可能会有些奇怪的问题,用的是类全局变量打开文件但在多线程中并未加锁,会导致文件有一定几率出现大小和源文件不同,即使文件大小相同,MD5值也不同,中间有一段是坏的...
java多线程下载文件源码,只能用炫酷来形容,感兴趣就下载看看吧
java多线程断点下载文件 ,文档介绍及代码实现
多线程下载文件,支持断点续传,下载文件信息保存到配置文件,如果异常中断,可以直接读取配置文件继续进行下载。已测试过4G以上的文件下载。
C# 多线程基本于httpwebrequest实现的下载功能 每个线程均可以通过事件追踪情况