肯定比放10毫秒的水要多。
多線程下載的實現過程:
1>首先得到下載文件的長度,然後設置本地文件
的長度。
RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd");
3>使用Http的Range頭字段指定每條線程從文件的什麼位置開始下載,下載到什麼位置爲止,如:指定從文件的2M位置開始下載,下載到位置(4M-1byte)爲止,代碼如下:
4>保存文件,使用RandomAccessFile類指定每條線程從本地文件的什麼位置開始寫入數據。
threadfile.seek(2097152);//從文件的什麼位置開始寫入數據
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class ThreadDowmLoad {
public static void main(String[] args) {
String path = "http://file1.51cto.com/index.php?aid=785088&k=205dfb403540e1ee182fd48c80247ab6&t=1347439680";
int threadNum = 3;
try {
new ThreadDowmLoad().downLoad(path, threadNum);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 從路徑中獲取下載文件名稱
*
* @param path下載文件的路徑
* @return 最後一個"/"後面字段的內容作爲下載後的文件名
*/
public static String getFileName(String path) {
// 獲得最後一個"/"後面字段的內容作爲下載後的文件名
return path.substring(path.lastIndexOf("/") + 1);
}
/**
* @param path下載文件的路徑
* @param threadNum線程數
* @throws Exception
*/
public void downLoad(String path, int threadNum) throws Exception {
URL url = new URL(path);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// 得到httpURLConnection對象進行相關設置
// 設置請求方式
httpURLConnection.setRequestMethod("GET");
// 設置鏈接超時時間
httpURLConnection.setConnectTimeout(5 * 1000);
// 通過getContentLength()取得下載長度
int downloadLength = httpURLConnection.getContentLength();
// 生成同長度的本地文件,存放下載數據-----RandomAccessFile隨機文件訪問類
String fileName = getFileName(path);// 從路徑中獲取下載文件名稱
// 通過相對路徑將下載後的文件保存到根目錄中
File saveFile = new File(fileName);
// "rwd"表示同步將文件下載到指定路徑中,沒有緩存,若沒有“d”則會有緩存不同步
RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,
"rwd");
// 保存在本地的文件長度=網絡下載的文件長度
randomAccessFile.setLength(downloadLength);
randomAccessFile.close();
// 計算每條線程下載的數據長度
int block = downloadLength % threadNum == 0 ? (downloadLength / threadNum)
: (downloadLength / threadNum) + 1;
// 計算每條線程開始下載與結束下載的位置
for (int i = 0; i < threadNum; i++) {
// 開線程下載各自的數據段
new DownLoadThread(url, saveFile, block, threadNum).start();
}
}
/**
*
* @author YanJun URL url, 路徑 File saveFile,文件名 int block, 數據段長度 int
* threadNum 指定線程
*/
private final class DownLoadThread extends Thread {
private URL url;
private File saveFile;
private int block;
private int threadNum;
public DownLoadThread(URL url, File saveFile, int block, int threadNum) {
super();
this.url = url;
this.saveFile = saveFile;
this.block = block;
this.threadNum = threadNum;
}
@Override
public void run() {
// 計算下載文件數據的開始和結束位置
int startPosition = threadNum * block;
int endPosition = (threadNum + 1) * block - 1;
try {
// 隨機文件訪問類
RandomAccessFile randomAccessFile = new RandomAccessFile(
saveFile, "rwd");
// 從什麼位置訪問數據randomAccessFile.seek(startPosition);
randomAccessFile.seek(startPosition);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
// 得到httpURLConnection對象進行相關設置
// 設置請求方式
httpURLConnection.setRequestMethod("GET");
// 設置鏈接超時時間
httpURLConnection.setConnectTimeout(5 * 1000);
// 使用Http的Range頭字段指定每條線程從文件的什麼位置開始下載,下載到什麼位置爲止,如:指定從文件的2M位置開始下載
httpURLConnection.setRequestProperty("Range", "bytes="
+ startPosition + "-" + endPosition);
// 取得輸入流
InputStream inputStream = httpURLConnection.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;// 當len=-1,表示流讀取完畢
// inputStream.read(buffer)--從輸入流裏讀取數據到緩衝區
while ((len = inputStream.read(buffer)) != -1) {
randomAccessFile.write(buffer, 0, len);
}
inputStream.close();
randomAccessFile.close();
System.out.println(threadNum + "號下載完成");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}