import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class Demo {
//线程个数
public static int threadCount = 3;
//线程下载完成的个数
public static int finishedCount = 3;
/**
* 多线程下载测试类
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//1、连接服务器,获取一个文件,获取文件的长度,在本地创建一个大小跟服务器文件一样大的临时文件
String path = "http://192.168.1.100:8080/test.avi";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if(code==200)
{
//服务器返回的数据长度 实际上就是文件的长度
int length = conn.getContentLength();
System.out.println("文件总长度:"+length);
//在客服端创建出来一个大小跟服务器端文件一样大小的临时文件
RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");
//指定创建的这个文件的长度
raf.setLength(length);
raf.close();
//假设是3个线程去下载资源
//平均每一个线程下载的文件的大小
int blockSize = length / threadCount;
for(int threadId=1;threadId<=threadCount;threadId++)
{
//线程下载的开始位置
int startIndex = (threadId-1)*blockSize;
int endIndex = threadId*blockSize;
if(threadId==threadCount)
{
endIndex = length;
}
System.out.println("线程:"+threadId+" 下载:---"+startIndex+"--->"+endIndex);
//启动线程
new DownloadThread(threadId,startIndex,endIndex,path).start();
}
}
else
{
System.out.println("服务器错误");
}
}
public static class DownloadThread extends Thread
{
private int threadId; //线程id
private int startIndex;
private int endIndex;
private String path;
public DownloadThread(int threadId, int startIndex, int endIndex,
String path) {
super();
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
}
public void run() {
try {
//检查是否存在记录文件下载长度的文件,如果存在读取这个文件的数据
File tempFile = new File(threadId+".txt");
if(tempFile.exists() && tempFile.length() >0)
{
FileInputStream fis = new FileInputStream(tempFile);
byte[] temp = new byte[1024];
int leng = fis.read(temp);
String downloadLen = new String(temp,0,leng);
int downloadLenInt = Integer.parseInt(downloadLen);
startIndex = downloadLenInt;
fis.close();
}
System.out.println("线程:"+threadId+"实际下载:---"+startIndex+"--->"+endIndex);
URL url = new URL(path);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//重要 : 请求服务器下载部分的文件指定文件的位置
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
//从服务器请求全部资源 200 ok 如果从服务器请求部分资源 206 ok
int code = conn.getResponseCode();
System.out.println("code:"+code);
//已经设置了请求的位置 返回的事当前位置对应的文件的输入流
InputStream is = conn.getInputStream();
//在客服端创建出来一个大小跟服务器端文件一样大小的临时文件
RandomAccessFile raf = new RandomAccessFile("test.avi", "rwd");
//随机写文件的时候从哪个位置开始
raf.seek(startIndex); //定位文件
int len = 0;
byte[] buffer = new byte[1024];
int total = 0;
while((len=is.read(buffer))!=-1)
{
//记录已经下载完成的长度
RandomAccessFile recordFile = new RandomAccessFile(threadId+".txt","rwd");
raf.write(buffer,0,len);
//下载完成的长度
total += len;
recordFile.write((total+startIndex +"").getBytes());
recordFile.close();
}
is.close();
raf.close();
System.out.println("线程:"+threadId+"下载完毕了。。。");
} catch (Exception e) {
e.printStackTrace();
}finally
{
//用于删除各个线程记录已经下载完成的长度的文件
finishedCount--;
//所有线程下载完成
if(finishedCount==0)
{
for(int i=1;i<=threadCount;i++)
{
//删除记录文件
File deleteFile = new File(i+".txt");
deleteFile.delete();
}
}
}
}
}
}
java 多线程断点下载功能
原创
©著作权归作者所有:来自51CTO博客作者好学Ace的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
java jdk的下载安装
jdk17在windows10 的下载及安装
java jdk17 windows10 -
HTTP方式文件分片断点下载
前言 在进行大文件或网络带宽不是很好的情况下,分片断点下载就会显得很有必要,目前各大下载
Range 分片下载 断点续传 java HTTP -
超大文件上传解决方案:分片断点上传
之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需求,都能得到满足。小小开心了一把。 但无论插件再怎么灵活,也难以应付所有的需求,比如,你要上传一个2
浏览器上传大文件的解决方案 内网上传大文件的解决方案 局域网上传大文件的解决方案 .net上传大文件的解决方案 asp.net上传大文件的解决方案 -
JAVA 超大文件上传解决方案:分片断点上传(一)
该说不说,最近这块挻火的。今天早上有网友加我微信,也是咨询这块的技术问题,最近不知道啥情况,加我的网友还
java 开发语言 解决方案 控件 上传