天天看點

Java實作多線程斷點下載下傳多線程下載下傳的原理圖實作的代碼要點:

多線程下載下傳的原理圖

Java實作多線程斷點下載下傳多線程下載下傳的原理圖實作的代碼要點:

實作的代碼

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);	
           

繼續閱讀