多線程下載下傳的原理圖
實作的代碼
public class MuThreadDownloader {
/**下載下傳線程數量*/
public static int threadCount = 3;
public static int runningThread = 3;
public static void main(String[] args) throws IOException {
String spec = "http://localhost:8083/aliww.exe";
URL url = new URL(spec);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(4000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if(code == 200){
int length = conn.getContentLength();
System.out.println("fileSize:" + length);
/**随機操作檔案類*/
RandomAccessFile raf = new RandomAccessFile("阿裡旺旺.exe", "rwd");
/**在本地建立一個同樣大小的臨時檔案*/
raf.setLength(length);
raf.close();
/**每個線程下載下傳的大小*/
int blockSize = length / threadCount;
for (int threadId = 1; threadId <= threadCount; threadId++) {
//每個線程下載下傳的起始位置
int startIndex = (threadId - 1) * blockSize;
//每個線程下載下傳的結束位置
int endIndex = threadId*blockSize - 1;
if(threadId == threadCount){
endIndex = length;
}
new DownLoaderThread(startIndex, endIndex, spec,threadId).start();
System.out.println("startIndex-endIndex " + startIndex + "-" + endIndex);
}
}
}
public static class DownLoaderThread extends Thread{
private int startIndex;
private int endIndex;
private String path;
private int threadId;
public DownLoaderThread(int startIndex, int endIndex, String path,int threadId) {
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
this.threadId = threadId;
}
@Override
public void run() {
try {
File file = new File(threadId + ".txt");
//每個線程下載下傳之前先判斷是否存在記錄進度的檔案
if(file.exists() && file.length() > 0){
InputStream is = new FileInputStream(file);
byte [] buffer = new byte[1024];
is.read(buffer);
System.out.println(new String(buffer));
startIndex = Integer.parseInt(new String(buffer).trim());
}
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//請求伺服器下載下傳部分的資源,指定資源的起始位置
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
conn.setConnectTimeout(5000);
//從伺服器傳回全部的資源傳回200 部分資源傳回206
int code = conn.getResponseCode();
System.out.println("code:" + code);
if(code == 206){
System.out.println("線程-" + threadId + "從" + startIndex + "位置開始下載下傳");
InputStream is = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile("阿裡旺旺.exe", "rwd");
//設定寫入檔案的起始位置
raf.seek(startIndex);
byte[] buff = new byte[1024];
int len = 0;
//用于記錄目前下載下傳的進度
int total = startIndex;
while((len = is.read(buff))!=-1){
raf.write(buff, 0, len);
total += len;
System.out.println("線程-" + threadId + "下載下傳到" + total + "位元組");
RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
accessFile.write(String.valueOf(total).getBytes());
accessFile.close();
// FileOutputStream fos = new FileOutputStream(file);
// fos.write(String.valueOf(total).getBytes());
// fos.flush();
// fos.close();
}
is.close();
raf.close();
runningThread -- ;
System.out.println("線程-" + threadId + "下載下傳完成......");
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(runningThread == 0){
for (int i = 1; i <= threadCount; i++) {
File file = new File(i + ".txt");
file.deleteOnExit();
}
}
}
}
}
}
要點:
1、告訴伺服器要請求部分資源
//請求伺服器下載下傳部分的資源,指定資源的起始位置
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);