DownUtil类
package loading;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.omg.CORBA.portable.InputStream;
public class DownUtil {
//定义下载资源的路径
private String path;
//定义所下载文件的保存位置
private String targetFile;
//定义需要使用多少个线程下载资源
private int threadNum;
//定义下载的线程对象
private DownThreads[] threads;
//定义下载文件的总大小
private int fileSize;
public DownUtil(String path,String targetFile,int threadNum)
{
this.path=path;
this.targetFile=targetFile;
this.threadNum=threadNum;
//初始化threads数组
threads=new DownThreads[threadNum];
}
//定义下载函数
public void download() throws Exception
{
URL url=new URL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+"application/x-shockwave-flash, application/xaml+xml, "
+"application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+"appliction/x-ms-application, application/vnd.ms-excel, "
+"application.vnds.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Connection", "Keep-Alive");
//得到文件大小
fileSize=conn.getContentLength();
conn.disconnect();
int currentPartSize=fileSize/threadNum+1;
RandomAccessFile file=new RandomAccessFile(targetFile,"rw");
//设置本地文件大小
file.setLength(fileSize);
file.close();
for(int i=0;i<threadNum;i++)
{
//计算每个线程下载的开始位置
int startPos=i*currentPartSize;
//每个线程使用一个RandomAccessFile进行下载
RandomAccessFile currentPart=new RandomAccessFile(targetFile, "rw");
//定义该线程的下载位置
currentPart.seek(startPos);
//创建下载线程
threads[i]=new DownThreads(startPos,currentPartSize,currentPart);
//启动线程
threads[i].start();
}
}
//获取下载的完成百分比
public double getCompleteRate()
{
//统计多个线程已经下载的总大小
int sumSize=0;
for(int i=0;i<threadNum;i++)
{
sumSize+=threads[i].length;
}
//返回已经完成的百分比
return sumSize*1.0/fileSize;
}
public class DownThreads extends Thread{
//当前线程的下载位置
private int startPos;
//当前线程负责下载的文件大小
private int currentPartSize;
//当前线程需要下载的文件块
private RandomAccessFile currrentPart;
//定义该线程已下载的字节数
public int length;
public DownThreads(int startPos, int currentPartSize, RandomAccessFile currentPart) {
// TODO Auto-generated constructor stub
this.startPos=startPos;
this.currentPartSize=currentPartSize;
this.currrentPart=currentPart;
}
public void run()
{
try
{
URL url=new URL(path);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5*1000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
+"application/x-shockwave-flash, application/xaml+xml, "
+"application/vnd.ms-xpsdocument, application/x-ms-xbap, "
+"appliction/x-ms-application, application/vnd.ms-excel, "
+"application.vnds.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
java.io.InputStream inStream=conn.getInputStream();
//跳过StartPos表明该线程只下载自己负责的那一部分
inStream.skip(this.startPos);
byte[] buffer=new byte[1024];
int hashRead=0;
//读取网络数据,并写入本地文件
while(length<currentPartSize&&(hashRead=inStream.read(buffer))!=-1)
{
currrentPart.write(buffer,0,hashRead);
//累计该线程下载的总大小
length+=hashRead;
}
//关闭线程
currrentPart.close();
inStream.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
MultiThreadDown类
package loading;
public class MultiThreadDown {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//初始化DownUitl对象
final DownUtil downUtil=new DownUtil("https://www.baidu.com/img/bd_logo1.png","D:\\bd_logo1.png",4);
//开始下载
downUtil.download();
new Thread(()->{
while(downUtil.getCompleteRate()<1)
{
//每隔一秒查询一次任务完成进度
System.out.println("已完成"+downUtil.getCompleteRate());
try{
Thread.sleep(1000);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
).start();
}
}