文件多線程下載
一、文件多線程下載步驟
1、 獲取網絡文件的長度,在android客戶端生成一個與網絡文件長度相等的空文件
2、 開啓N條線程下載文件,計算每條線程負責下載的數據量
3、 依次創建,啓動多條線程分別從網絡文件的不同位置下載數據,並從本地文件的相同位置寫入數據,要計算出每條線程從網絡文件的什麼位置開始下載數據,到什麼位置結束下載
具體步驟
1、 打開HTTP協議的連接對象,爲對象設置屬性
//path爲源路徑
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
2、判斷請求是否成功
if(conn.getResponseCode() == 200){
//步驟3 4 5 6
}
(以下步驟均在請求成功的基礎上去實實現)
3、取得網絡文件的長度
int length = conn.getContentLength();
4、隨機文件訪問類來生成一個與網絡文件長度相等的本地文件
1>取得網絡文件名稱
String filename = path.substring(path.lastIndexOf("/")+1);//從最後一個"/"開始獲取
2>創建文件
File file = new File(mubiao,filename); // mubiao指文件保存路徑 filename爲文件名稱
3>隨機文件訪問
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd");
4>設置文件長度
accessFile.setLength(length);
accessFile.close();
5、計算每個線程負責下載的數據量
int block = length%threadsize == 0 ? length/threadsize :length/threadsize +1;
6、循環實現線程的下載
for(int threadid = 0 ;threadid<threadsize;threadid++){
new DownloadThread(threadid,block,url,file).start();
}
7、創建線程類實現下載
private class DownloadThread extends Thread{
private int threadid;
private int block;
private URL url;
private File file;
public DownloadThread(int threadid, int block, URL url, File file) {
this.threadid=threadid;
this.block=block;
this.url=url;
this.file=file;
}
public void run(){
//計算該線程從網絡文件的什麼位置開始下載
int start = threadid * block ;
//下載到什麼位置結束
int end= (threadid+1) * block-1 ;
try{
//建隨機文件訪問類對象
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd");
//指定從本地文件的某一個位置寫入數據
accessFile.seek(start);
//請求網絡文件某一個區域的數據
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes="+start+"-"+end);
if(conn.getResponseCode() == 206){
InputStream instream = conn.getInputStream();
//循環讀入數據
byte[] buffer = new byte[1024];
int len=0; //返回的讀取到的長度
while((len = instream.read(buffer))!=-1){
//-------將數據寫入本地文件
accessFile.write(buffer,0,len);
}
accessFile.close();
instream.close();
// System.out.println(threadid+1+"線程下載完成") ;
}
else{
// System.out.println(threadid+1+"線程下載失敗") ;
}
}catch(Exception e){
e.printStackTrace();
}
}
}
重寫線程的run方法
1>計算該線程從網絡文件的什麼位置開始下載
int start = threadid * block ;
2>下載到什麼位置結束
int end= (threadid+1) * block-1 ;
3>建隨機文件訪問類對象
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd");
4>指定從本地文件的某一個位置寫入數據
accessFile.seek(start);
5>請求網絡文件某一個區域的數據
1 得到HttpURLConnection對象,並設置屬性
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
2 使用HTTP的Range頭字段指定每條線程從文件的什麼位置開始下載
下載到什麼位置結束
conn.setRequestProperty("Range", "bytes="+start+"-"+end);
3 判斷請求是否成功斷點下載的返回碼爲206
if(conn.getResponseMethod()==206){
// 步驟4
}
4 得到輸入流,通過輸入流得到數據,將數據寫入本地文件
InputStream instream = conn.getInputStream();
//循環讀入數據
byte[] buffer = new byte[1024];
int len=0; //返回的讀取到的長度
while((len = instream.read(buffer))!=-1){ //如果不爲-1 說明數據沒有讀完
//-------將數據寫入本地文件
accessFile.write(buffer,0,len);
}
accessFile.close();
instream.close();