Java开发之多线程下载和断点续传
代码实现了多线程下载和断点续传功能
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL; import javax.print.attribute.standard.Finishings; public class MultiDownload { static int ThreadCount = 3;
static int finishedThread = 0;
//确定下载地址
static String path = "http://192.168.13.13:8080/QQPlayer.exe";
public static void main(String[] args) { //发送get请求,请求这个地址的资源
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000); if(conn.getResponseCode() == 200){
//拿到所请求资源文件的长度
int length = conn.getContentLength(); File file = new File("QQPlayer.exe");
//生成临时文件
RandomAccessFile raf = new RandomAccessFile(file, "rwd");
//设置临时文件的大小
raf.setLength(length);
raf.close();
//计算出每个线程应该下载多少字节
int size = length / ThreadCount; for (int i = 0; i < ThreadCount; i++) {
//计算线程下载的开始位置和结束位置
int startIndex = i * size;
int endIndex = (i + 1) * size - 1;
//如果是最后一个线程,那么结束位置写死
if(i == ThreadCount - 1){
endIndex = length - 1;
}
// System.out.println("线程" + i + "的下载区间是:" + startIndex + "---" + endIndex);
new DownLoadThread(startIndex, endIndex, i).start();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
class DownLoadThread extends Thread{
int startIndex;
int endIndex;
int threadId; public DownLoadThread(int startIndex, int endIndex, int threadId) {
super();
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadId = threadId;
} @Override
public void run() {
//再次发送http请求,下载原文件
try {
File progressFile = new File(threadId + ".txt");
//判断进度临时文件是否存在
if(progressFile.exists()){
FileInputStream fis = new FileInputStream(progressFile);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
//从进度临时文件中读取出上一次下载的总进度,然后与原本的开始位置相加,得到新的开始位置
startIndex += Integer.parseInt(br.readLine());
fis.close();
}
System.out.println("线程" + threadId + "的下载区间是:" + startIndex + "---" + endIndex);
HttpURLConnection conn;
URL url = new URL(MultiDownload.path);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
//设置本次http请求所请求的数据的区间
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex); //请求部分数据,相应码是206
if(conn.getResponseCode() == 206){
//流里此时只有1/3原文件的数据
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
int total = 0;
//拿到临时文件的输出流
File file = new File("QQPlayer.exe");
RandomAccessFile raf = new RandomAccessFile(file, "rwd");
//把文件的写入位置移动至startIndex
raf.seek(startIndex);
while((len = is.read(b)) != -1){
//每次读取流里数据之后,同步把数据写入临时文件
raf.write(b, 0, len);
total += len;
// System.out.println("线程" + threadId + "下载了" + total); //生成一个专门用来记录下载进度的临时文件
RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd");
//每次读取流里数据之后,同步把当前线程下载的总进度写入进度临时文件中
progressRaf.write((total + "").getBytes());
progressRaf.close();
}
System.out.println("线程" + threadId + "下载完毕-------------------小志参上!");
raf.close(); MultiDownload.finishedThread++;
synchronized (MultiDownload.path) {
if(MultiDownload.finishedThread == MultiDownload.ThreadCount){
for (int i = 0; i < MultiDownload.ThreadCount; i++) {
File f = new File(i + ".txt");
f.delete();
}
MultiDownload.finishedThread = 0;
}
} }
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Java开发之多线程下载和断点续传的更多相关文章
- Android开发之多线程下载、断点续传、进度条和文本显示
代码实现了在Android环境下的多线程下载.断点续传.进度条显示和文本显示百分数: import java.io.BufferedReader; import java.io.File; impor ...
- Android学习记录(5)—在java中学习多线程下载之断点续传②
在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...
- java多线程下载和断点续传
java多线程下载和断点续传,示例代码只实现了多线程,断点只做了介绍.但是实际测试结果不是很理想,不知道是哪里出了问题.所以贴上来请高手修正. [Java]代码 import java.io.File ...
- Android学习记录(6)—将java中的多线程下载移植到Android中(即多线程下载在Android中的使用)③
在这一节中,我们就来讲多线程下载以及断点续传在android中怎么使用,前两节是为本节做准备的,没有看前两节的同学,最好看完前面的两篇文章再来看这篇.其实在android端的应用和java基本上是差不 ...
- Android学习记录(4)—在java中学习多线程下载的基本原理和基本用法①
多线程下载在我们生活中非常常见,比如迅雷就是我们常用的多线程的下载工具,当然还有断点续传,断点续传我们在下一节来讲,android手机端下载文件时也可以用多线程下载,我们这里是在java中写一个测试, ...
- Android 多线程下载,断点续传,线程池
你可以在这里看到这个demo的源码: https://github.com/onlynight/MultiThreadDownloader 效果图 这张效果图是同时开启三个下载任务,限制下载线程数量的 ...
- Java 仿迅雷多线程下载
package net.webjoy.jackluo.android_json; /** * 1.http Range "bytes="+ start+end * 2.Random ...
- java开发的web下载大数据时的异常处理
同事用java开发了一个系统,其中有一个功能是下载大约10万笔数据到Excel中.当上线后,很多用户反映下载数据量大的时候就不能成功,但有时可以,所以结论就是系统不稳定,这个问题拖了很久没有解决. 在 ...
- 【Java】:多线程下载
import java.io.InputStream; import java.io.RandomAccessFile; import java.net.URL; import java.net.UR ...
随机推荐
- MIT 2012 分布式课程基础源码解析-底层通讯实现
本节内容和前节事件管理封装是息息相关的,本节内容主要包含的代码在connection{.h, .cc}中. 这里面最主要的有两个类:connection类和tcpsconn类,connetion类主要 ...
- 用端口映射在Apache中对每个项目分配端口,实现一个端口访问一个网站
映口映射的功能主要就是实际互联网可以访问当前进行映射的电脑,首先我们要进行路由器的端口映射,常见的开放端口有80,21,3389等,80是网站常用端口,21是FTP服务器常用端口,3389是远程桌面连 ...
- javascript跨域解决方案
最近遇到了https跨域访问http域的问题,很多朋友理所当然的认为简单,问题是https跨域访问到http域上的资源,会进行相互通信,没有解决该问题,只能把外部资源扔到了新浪的sae上,通过http ...
- 购买 CDRTools 2 正式版
联系方式: Email:396390927@qq.com QQ: 396390927 QQ群: 26326434 组件价格: ¥50元/用户,免费更新: 此物为数字商品,并经过测试完全可用,谢 ...
- [Git]代码管理工具简单使用
1 Git简介 Git是分布式的版本控制系统,是Linux内核开发者林纳斯·托瓦兹(Linus Torvalds)为更好地管理Linux内核开发而设计.与CVS.Subversion一类的集中式版本控 ...
- 父子进程间通信模型实现(popen)
0.FILE *popen(const char *command, const char *type); popen 函数相当于做了以下几件事: 1.创建一个无名管道文件 2. fork() 3.在 ...
- Inside of Jemalloc
INSIDE OF JEMALLOCThe Algorithm and Implementation of Jemalloc author: vector03mail: mmzsmm@163.co ...
- sybase下convert函数第三个参数(时间格式)
convert(varchar(10),字段名,转换格式) 比如:1.select user_id,convert(varchar(10),dayts,11) as dates from tb_use ...
- W25Q32的使用
一.W25Q32简介 W25Q32是华邦公司推出的大容量“SPI FLASH” 产品. 1.容量 32M-Bit/4M-byte(4,194,304) 2.存储结构 页:256-bytes 扇区:4 ...
- linux内核驱动中_IO, _IOR, _IOW, _IOWR 宏的用法与解析(引用)
在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个 ...