废话少说上代码
package com.yc.net.http01;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.text.NumberFormat;
//加快下载速度使用多线程
//1.怎么拆分多段
//2.怎么进行 多段下载 ,使用请求报头 Range:bytes=开始字节位置-结束字节位置
//3.多段下载后合并 的结果 使用随机存储流 RandomAccessFile进行合并
public class XueLei02 {
public static void main(String[] args) {
try {
XueLei02 x1=new XueLei02();
URL url=new URL("http://dlsw.baidu.com/sw-search-sp/soft/ca/13442/Thunder_dl_7.9.41.5020_setup.1444900082.exe");
int threadSize=5;//线程数
//1.怎么拆分多段
final long totalSize=x1.getTotalLength(url, threadSize);
Long perLength=totalSize %threadSize==0 ?totalSize/threadSize :(totalSize/threadSize +1);
String path="d:\\Thunder04"+System.currentTimeMillis()+".exe";
long freeSpace =getFileFreeSpace(path);
if(totalSize>=freeSpace-1024L*1024*1024*86){//判断下载空间是否充足
System.out.println("可用空间不足,请清理磁盘后再下载。。。。");
return;//不继续向下执行
}
//监听下载文件大小的对象
CountDownloadSizeListener cds1=new CountDownloadSizeListener(){
long dowmloadSize=0;
@Override
public void CountSize(int size) {
dowmloadSize+=size;//统计每一次下载文件的大小
//下载的百分比
double percent=dowmloadSize *1.0/totalSize;
//获得百分比格式化对象
NumberFormat nf=NumberFormat.getPercentInstance();
nf.setMinimumFractionDigits(2);
System.out.println("下载进度:"+nf.format(percent));
}
};
for(int i=0;i<5;i++){
new DownloadFile(url,i,perLength,path,cds1).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//取到文件所在目录的可用空间
private static long getFileFreeSpace(String path) {
File f=new File(path);
File parentFile=f.getParentFile();//取得文件目录
return parentFile.getFreeSpace();//取到目录的可用空间大小
}
//取到每个线程下载的长度
private Long getTotalLength(URL url,int threadSize) {
try {
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("HEAD");
long totalSize=con.getContentLengthLong();
System.out.println(totalSize+"=="+con.getContentLength());
return totalSize;
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
class DownloadFile extends Thread{
private URL url;//下载地址
private int threadId;//下载标号
private long threadFileSize;//线程文件的下载长度
private String path;//合并的文件
private CountDownloadSizeListener cds1;
public DownloadFile( URL url, int threadId,
long threadFileSize, String path,CountDownloadSizeListener cds1) {
super();
this.url = url;
this.threadId = threadId;
this.threadFileSize = threadFileSize;
this.path = path;
this.cds1=cds1;
}
public void run(){
//请求
try {
HttpURLConnection con=(HttpURLConnection) url.openConnection();//获得连接对象
// con.setRequestMethod("HEAD"); //设置请求方式 head get post.....
con.setRequestMethod("GET");
long start=threadId *threadFileSize;
long end=(threadId+1)*threadFileSize-1;
con.setRequestProperty("Range", "bytes="+start+"-"+end);
con.setConnectTimeout(10000);
InputStream in=con.getInputStream();
RandomAccessFile raf=new RandomAccessFile(path,"rwd");
byte[] bs=new byte[1024*1024];
int length=0;
raf.seek(start);
while((length=in.read(bs))!=-1){
raf.write(bs,0,length);
cds1.CountSize(length);
}
in.close();
raf.close();
System.out.println("第"+threadId+"个线程下载成");
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}