package com.zuoye.demo.D0721;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class Test {
public static void main(String[] args) {
//需要请求的url
String path = "http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe";
//三个线程
int threadCount = 3;
try {
//创建URL对象
URL url = new URL(path);
//打开URL对应的服务器连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");//设置get提交
conn.setConnectTimeout(5000);//设置连接超时时间
conn.setReadTimeout(5000);//设置读取超时时间
//获取状态码
int responseCode = conn.getResponseCode();
System.out.println("responseCode = " + responseCode);
//如果正确响应 200
if(responseCode==200){
//获取文件的大小,为什么要获取文件的大小?假如三个线程
int contentLength = conn.getContentLength();
System.out.println("文件总大小 = " + contentLength);
//切割为三份,计算每份的大小
int size = contentLength/threadCount;
/*
假如 contentLength=10 zize=3
线程1:i*size-(i+1)*size 0-3
线程2:i*size-(i+1)*size 3-6
线程3:i*size-contentLenth 6-10
*/
for (int i = 0; i < threadCount; i++) {
//创建子线程,下载一段
DownloadThread dt = new DownloadThread();
dt.setName("线程"+(i+1));
dt.setPath(path);
dt.setStart(i*size);//设置此段开始位置
if(i==2){
dt.setEnd(contentLength);//设置此段结束位置
}else{
dt.setEnd((i+1)*size);//设置此段结束位置
}
//启动线程,开始下载
dt.start();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class DownloadThread extends Thread{
private String path; //网址
private long start; //开始的位置
private long end; //结束的位置
@Override
public void run() {
//需要请求的url
String path = "http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe";
try {
//创建URL对象
URL url = new URL(path);
//打开URL对应的服务器连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");//设置get提交
conn.setConnectTimeout(5000);//设置连接超时时间
conn.setReadTimeout(5000);//设置读取超时时间
conn.setRequestProperty("Range","bytes="+start+"-"+end);//设置下载的分段(从start-end)
//获取状态码
int responseCode = conn.getResponseCode();
System.out.println("responseCode = " + responseCode);
//分段下载,如果正确响应 206
if(responseCode==206){
//下载...
InputStream in = conn.getInputStream();//输入流,用来读取网络资源
//从响应头获取要下载的文件名
String headerField = conn.getHeaderField("Content-Disposition");
String field = headerField.split(";")[1];
String fileName = field.substring(field.indexOf("\"")+1,field.lastIndexOf("\""));
//System.out.println(fileName);
File file = new File(fileName);
//下载,写入数据到文件
RandomAccessFile raf = new RandomAccessFile(file,"rwd");//可读可写有权限
raf.seek(start);//设置从文件的什么位置开始写
//读一组,写一组
int len = 0;
byte[]bytes=new byte[1024];
while((len = in.read(bytes))!=-1){
raf.write(bytes,0,len);//读len个,写len个
}
//关闭流,释放资源
raf.close();
in.close();
System.out.println(this.getName()+":已经下载完毕..");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public long getStart() {
return start;
}
public void setStart(long start) {
this.start = start;
}
public long getEnd() {
return end;
}
public void setEnd(long end) {
this.end = end;
}
}