import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadThread extends Thread {
private File saveFile;
private URL downUrl;
private int block;
private int threadId = -1;
private CallBack callback;
private DownLoadCallBack downLoadCallBack;
private int downloadSize;
private Messages messages;
public DownloadThread(URL downUrl, File saveFile, int block, int downloadSize, int threadId, Messages messages, CallBack callback, DownLoadCallBack downLoadCallBack) {
this.downLoadCallBack = downLoadCallBack;
this.downUrl = downUrl;
this.saveFile = saveFile;
this.block = block;
this.threadId = threadId;
this.callback = callback;
this.downloadSize = downloadSize;
this.messages = messages;
}
@Override
public void run() {
HttpURLConnection conn = null;
InputStream inStream = null;
RandomAccessFile threadfile = null;
try {
conn = (HttpURLConnection) downUrl.openConnection();
conn.setRequestMethod(Constant.GET);
conn.setReadTimeout(1000 * 8);
int startPos = block * (threadId - 1) + downloadSize;//开始位置
int endPos = block * threadId -1;//结束位置
conn.setRequestProperty("Range", "bytes=" + startPos + "-"+ endPos);//设置获取实体数据的范围
if(conn.getResponseCode() == HttpURLConnection.HTTP_PARTIAL){
inStream = conn.getInputStream();
byte[] buffer = new byte[Constant.BUFFER * 10];
int offset = 0;
threadfile = new RandomAccessFile(saveFile, "rwd");
threadfile.seek(startPos);
String key = Constant.THREADID + String.valueOf(threadId);
//messages,文件总大小,下载的当前大小
while (!downLoadCallBack.getExit() && (offset = inStream.read(buffer)) != -1) {
threadfile.write(buffer, 0, offset);
downLoadCallBack.append(offset);
downloadSize += offset;
downLoadCallBack.update(key, String.valueOf(downloadSize));
int size = downLoadCallBack.getDownloadLength();
messages.setCurrentDownloadSize(size);
callback.schedule(messages);
}
}
} catch (IOException e) {
downLoadCallBack.setExit(true);
messages.setM
Java--多线程断点下载 (二)
this.threads = new DownloadThread[threadNum];
this.isNext = false;
this.call_total = threadNum;
this.downloadSize = 0;
this.downloadLength = 0;
this.messages = messages;
this.exit = false;
}
/**
* 开始下载文件
*/
public void download(String downloadUrl, long size){
try {
messages.setTotalDownloadSize(size);
saveFile = new File(savePath);
RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rw");
accessFile.setLength(size);
accessFile.close();
block = (int) ((size % this.threads.length) == 0 size
/ this.threads.length : size / this.threads.length + 1);
URL url = new URL(downloadUrl);
propertiesHelper = new PropertiesHelper(configPath);
//如果配置文件不存在,则创建
if(!FileOperate.isFileExist(configPath)){
FileOperate.createFile(configPath, false);
initProperties();
}else{
datas = propertiesHelper.getAllProperties();
if(datas.size() == 0) initProperties();
}
for(int i = 0; i < threads.length; i++){
String value = datas.get(Constant.THREADID + (i + 1));
if(value == null) value = "0";
downloadSize = Integer.parseInt(value);
downloadLength += downloadSize;
}
for (int i = 0; i < threads.length; i++) {// 开启线程进行下载
String value = datas.get(String.valueOf(Constant.THREADID + (i + 1)));
if(value == null) value = "0";
downloadSize = Integer.parseInt(value);
if(downloadSize == block){
call_curr++;
if(call_curr == call_total){
isNext = true;
break;
}
continue;
}
threads[i] = new DownloadThread(url, saveFile, block,
downloadSize, i + 1, messages, callback, this);
threads[i].setPriority(7);
threads[i].start();
}
while(!isNext());
} catch (IOException e) {
messages.setMsg("FileDownloader:download:" + e.getMessage());
callback.fail(messages);
}
}
private synchronized boolean isNext() {
return isNext;
}
private void initProperties() {
for(int i = 0; i < threads.length; i++){
propertiesHelper.setProperties(Constant.THREADID + (i + 1), "0");
}
datas = propertiesHelper.getAllProperties();
}
@Override
public synchronized void isFinished() {
call_curr++;
if (call_curr == call_total){
isNext = true;
}
}
public synchronized void update(String key, String value){
propertiesHelper.setProperties(key, value);
}
@Override
public synchronized int getDownloadLength() {
return downloadLength;
}
@Override
public synchronized void append(int size) {
downloadLength += size;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public String getConfigPath() {
return configPath;
}
public void setConfigPath(String configPath) {
this.configPath = configPath;
}
@Override
public boolean getExit() {
return exit;
}
@Override
public void setExit(boolean isExit) {
exit = isExit;
}
}