Java多線程下載代碼

package com.java.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;

class Download extends Thread{
	
	//定義字節數組(取水的竹筒)的長度
	private final int BUFF_LEN = 32;
	//定義下載的起始點
	private long start;
	//定義下載的結束點
	private long end;
	//下載資源對應的輸入流
	private InputStream is;
	//將下載的字節輸出到raf中
	private RandomAccessFile raf;
	
	public Download() {

	}
	
	public Download(long start, long end, InputStream is, RandomAccessFile raf) {
		System.out.println(start + "---------->" + end);
		this.start = start;
		this.end = end;
		this.is = is;
		this.raf = raf;
	}
	
	@Override
	public void run() {
		try {
			is.skip(start);
			raf.seek(start);
			//定義讀取輸入流內容的緩存數組(竹筒)
			byte[] buff = new byte[BUFF_LEN];
			//本線程負責下載資源的大小
			long contentLen = end - start;
			//定義最多需要讀取幾次就可以完成本線程下載
			long times = contentLen / BUFF_LEN + 4;
			//實際讀取的字節
			int hasRead = 0;
			for(int i=0; i<times; i++){
				hasRead = is.read(buff);
				if(hasRead < 0){
					break;
				}
				raf.write(buff, 0, hasRead);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(is != null) is.close();
				if(raf != null) raf.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
}

public class MutilDown {
	public static void main(String[] args) {
		final int DOWN_THREAD_NUM = 4;
		final String OUT_FILE_NAME = "e:/down.jpg";
		InputStream[] isArr = new InputStream[DOWN_THREAD_NUM];
		RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];
		try {
			URL url = new URL("http://www.blueidea.com/articleimg/2006/08/3912/images/plant4.jpg");
			//依次URL打開一個輸入流
			isArr[0] = url.openStream();
			long fileLen = getFileLength(url);
			System.out.println("網絡資源的大小:" + fileLen);
			outArr[0] = new RandomAccessFile(OUT_FILE_NAME, "rw");
			for(int i=0; i<fileLen; i++){
				outArr[0].write(0);
			}
			long numPerThred = fileLen / DOWN_THREAD_NUM;
			//整個下載資源整除後剩下的餘數
			long left = fileLen % DOWN_THREAD_NUM;
			for(int i=0; i<DOWN_THREAD_NUM; i++){
				//爲每條線程打開一條輸入流,一個RandomAccessFile對象
				//讓每個線程分別下載文件的不同部分
				if(i != 0){
					//以URL打開多個輸入流
					isArr[i] = url.openStream();
					outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
				}
				//分別啓動多個線程來下載網絡資源
				if( i == DOWN_THREAD_NUM - 1){
					//最後一個線程下載指定numPerThred + left個字節
					new Download(i * numPerThred, (i + 1) * numPerThred + left, isArr[i], 
							outArr[i]).start();
				}else{
					//每個線程負責下載一定的numPerThred個字節
					new Download(i * numPerThred, (i + 1) * numPerThred, isArr[i], outArr[i]).start();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//定義獲取指定網絡資源的方法
	public static long getFileLength(URL url) throws IOException{
		long length = 0;
		//打開URL對應的URLConnection
		URLConnection con = url.openConnection();
		long size = con.getContentLength();
		length = size;
		return length;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章