packagedemo;importjava.io.BufferedReader;importjava.io.File;importjava.io.FileInputStream;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.RandomAccessFile;importjava.net.HttpURLConnection;importjava.net.URL;public classMutilDownLoad {//定义下载的路径
private static String path = "http://192.168.87.1:8080/lol.exe";//假设开三个线程
private static final int threadCount = 3;//代表当前正在运行的线程
private static intrunningThread;public static voidmain(String[] args) {try{
URL url= newURL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);int code =conn.getResponseCode();if (code == 200) {int length =conn.getContentLength();
runningThread=threadCount;
System.out.println("length:" +length);
RandomAccessFile rafAccessFile= new RandomAccessFile(getFilename(path), "rw");
rafAccessFile.setLength(length);int blockSize = length /threadCount;for (int i = 0; i < threadCount; i++) {int startIndex = i *blockSize;int endIndex = (i + 1) * blockSize - 1;if (i == threadCount - 1) {
endIndex= length - 1;
}
System.out.println("线程id:::" + i + "理论下载的位置" + ":" + startIndex + "-----" +endIndex);
DownLoadThread downLoadThread= newDownLoadThread(startIndex, endIndex, i);
downLoadThread.start();
}
}
}catch(Exception e) {
e.printStackTrace();
}
}private static class DownLoadThread extendsThread {private intstartIndex;private intendIndex;private intthreadId;public DownLoadThread(int startIndex, int endIndex, intthreadId) {this.startIndex =startIndex;this.endIndex =endIndex;this.threadId =threadId;
}
@Overridepublic voidrun() {try{
URL url= newURL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
File file= new File(getFilename(path) + threadId + ".txt");if (file.exists() && file.length() > 0) {
FileInputStream fis= newFileInputStream(file);
BufferedReader bufr= new BufferedReader(newInputStreamReader(fis));
String lastPositionn=bufr.readLine();int lastPosition =Integer.parseInt(lastPositionn);
startIndex= lastPosition + 1;
System.out.println("线程id::" + threadId + "真实下载的位置" + ":" + startIndex + "-----" +endIndex);
fis.close();
}
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" +endIndex);int code =conn.getResponseCode();if (code == 206) {
RandomAccessFile raf= new RandomAccessFile(getFilename(path), "rw");
raf.seek(startIndex);
InputStream in=conn.getInputStream();int len = -1;byte[] buffer = new byte[1024 * 1024];//1Mb
int total = 0;while ((len = in.read(buffer)) != -1) {
raf.write(buffer,0, len);
total+=len;//实现断点续传 就是把当前线程下载的位置 给存起来 下次再下载的时候 就是按照上次下载的位置继续下载//存到一个普通的.txt文本中
int currentThreadPosition = startIndex +total;
RandomAccessFile raff= new RandomAccessFile(getFilename(path) + threadId + ".txt", "rwd");
raff.write(String.valueOf(currentThreadPosition).getBytes());
raff.close();
}
raf.close();
System.out.println("线程id:" + threadId + "---下载完毕了");//把.txt文件删除 每个线程具体什么时候下载完毕了 我们不知道//线程同步锁
synchronized (DownLoadThread.class) {
runningThread--;if (runningThread == 0) {//所有的线程都执行完毕了 就把.txt文件删除
for (int i = 0; i < threadCount; i++) {
File delteFile= new File(getFilename(path) + i + ".txt");
delteFile.delete();
}
}
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
}//获取文件的名字
public staticString getFilename(String path) {int start = path.lastIndexOf("/") + 1;returnpath.substring(start);
}
}