📄 multithreadgetfile.java
字号:
package com.downfile;
/**
* 多线程下载调度程序
*/
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.StringTokenizer;
/**
* 多线程下载调度程序
*/
public class
MultiThreadGetFile extends Thread {
long startPos = 0, endPos = 0;
String currentFileThreadName; //要带上完整的路径
String urlFile; //网络文件地址
String urlFileName; //网络文件名
String localFileAddress; //下载文件要存放的地址
String localFileAddress0; //用于保留原始地址
int threadNum; //要同时下载的线程数
long[] eachThreadLength; //每个线程要下功的文件分块的大小
long urlFileLength; //网络文件的大小
URL url;
HttpURLConnection httpURLConnection;
String tempDirctoryHead = "tmp"; //用于存放下载文件的临时文件夹的前面部份,这里为"tmp"
String tempStoreDirectory;
FileDownInformationWithXML xmlFile;
//public static boolean[] checkList; //检测线程
//是否有必要建立下载文件存存放目录,如果是已经下了部份文件,就不用,采用断点续传的方式
boolean needCreateNewDirectory = true;
public MultiThreadGetFile() {
}
public MultiThreadGetFile(String urlFile, int threadNum,
String localFileAddress) {
this.urlFile = urlFile;
this.threadNum = threadNum; //要同时下载的线程数
if (createDirectory(localFileAddress) == false) {
System.out.println("创建文件夹失败,请确认您是否有权限!");
return;
}
this.localFileAddress = localFileAddress;
this.localFileAddress0 = localFileAddress;
xmlFile = new FileDownInformationWithXML(localFileAddress);
//确定在XML文件中是否存在下载记录,没有返回null值
String localFileAddressNow = xmlFile.downFileExist(urlFile);
if (localFileAddressNow != null) { //如果存在
this.localFileAddress = localFileAddressNow;
needCreateNewDirectory = false;
} else {
//不存在就增加一个下载项到XML文件中去
//这里一定要同步,否则其它的线程访问的时候由于这个线程已经对这个程序的更改
//那么访问所得到的结果是不一样的
//在文件合并中,也是一样需要实现线程同步的
synchronized (this) {
xmlFile.addOneDownRecord(urlFile,
getTempStoreDirectory(localFileAddress));
xmlFile.saveChange();
}
}
}
private String getTempStoreDirectory(String localFileAddress) {
//否则就建立新的目录
String tempDirctory = localFileAddress + tempDirctoryHead;
//如果是断点续传,那么断点续传的目录就是从XML文件中取得的目录,其它的就不管了
if (needCreateNewDirectory == false)
return localFileAddress;
String tNum = "";
while (true) {
tempDirctory = tempDirctory + tNum;
File file = new File(tempDirctory);
if (!file.exists()) {
break;
}
tNum = "0";
}
return tempDirctory;
}
/**
* @localFileAddress 存放文件的路径
* 该函数主要是在本地路径不存在的情况下,创建本地存放路径,是真假返回创建结果
*/
private boolean createDirectory(String localFileAddress) {
File file = new File(localFileAddress);
if (!file.exists()) {
try {
file.mkdir();
} catch (Exception e) {
return false;
}
}
return true;
}
/**
* 确定每个线程文件最终要写的文件在大小
*/
private void init_getEachThreadLength() {
long l;
l = urlFileLength / threadNum;
for (int i = 0; i < threadNum; i++) {
if (i == threadNum - 1) //如果是分配最后一个线程了
{
eachThreadLength[i] = urlFileLength - i * l;
} else
eachThreadLength[i] = l;
}
}
/**
* 取得要下载的文件名
* @param file 网络文件名及路径
* @return 文件名及扩展名
*/
private String GetFileName(String file) {
StringTokenizer st = new StringTokenizer(file, "/");
while (st.hasMoreTokens()) {
file = st.nextToken();
}
return file;
}
private void init() {
tempStoreDirectory = getTempStoreDirectory(localFileAddress);
if (needCreateNewDirectory == true) {
if (createDirectory(tempStoreDirectory) == false) //创建一个临时文件夹
{
System.out.println("创建文件夹失败,请确认您是否有权限!");
return;
}
}
eachThreadLength = new long[threadNum];
try {
url = new URL(urlFile);
httpURLConnection = (HttpURLConnection)url.openConnection();
urlFileLength =
Long.parseLong(httpURLConnection.getHeaderField("Content-Length"));
urlFileName = url.getFile(); //取得在服务器上的路径及文件名
urlFileName = GetFileName(urlFileName); //取得文件名
init_getEachThreadLength();
httpURLConnection.disconnect();
//checkList = new boolean[threadNum + 1];
for (int i = 1; i <= threadNum; i++) {
if (i > 1)
startPos = startPos + eachThreadLength[i - 2];
endPos = startPos + eachThreadLength[i - 1];
currentFileThreadName =
tempStoreDirectory + "\\" + urlFileName + ".part" + i;
//System.out.println("startPos:"+(startPos));
//System.out.println("endPos:"+(endPos));
//System.out.println("Size:"+(endPos-startPos));
Thread thread =
new Thread(new GetFileThread(urlFile, startPos, endPos,
currentFileThreadName, i));
thread.start();
//checkList[i] = false; //表示该线程开始
}
//System.out.println("localFileAddress:"+localFileAddress0);
//System.out.println("tempStoreDirectory:"+tempStoreDirectory);
Thread policeThread =
new Thread(new PoliceThread(threadNum, localFileAddress0,
tempStoreDirectory,urlFile));
policeThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
init();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -