HttpURLConnection方法之setRequestProperty()淺談
阿新 • • 發佈:2019-02-01
【問題】關於從網上下載一個檔案分多個執行緒同時下載。
主要使用到HttpURLConnection物件的setRequestProperty(String key,String value);
方法簡單說一下如何使用,setRequestProperty()方法嚴格上講是HttpURLConnection的父類---URLConnection的方法,而URL.openConnection()返回的是一個URLConnection
物件,而一般我們都用他的子類HttpURLConnection去做連結和網路傳輸工作。
【解決思路總述】
1,把指定檔案(通過HttpURLConnection.getContentLength();獲得檔案大小),分成指定執行緒數下載,或者指定每個執行緒承擔下載任務的大小(再次我們僅以後者分析)
2,計算所需執行緒數
3,將獲得的資料儲存本地(使用RandomAccessFile流儲存)
【程式碼】
package com.wsf.demo; import java.io.BufferedInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class ImageDownload { public final static String sate = "http://www.baidu.com/img/bd_logo1.png";//本題所下載的檔案是一個百度圖示 public static void main(String[] args) { try { //建立一個URL物件 URL url = new URL(sate); //建立一個連結 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //制定相應方式 conn.setRequestMethod("GET"); //進行連線 conn.connect(); //獲得響應碼 int code = conn.getResponseCode(); //獲得檔名字 int position = sate.lastIndexOf("/"); String fileName = sate.substring(position+1); System.out.println("伺服器響應碼:"+code); //如果響應碼是200 則連結下載。。。 if(code == HttpURLConnection.HTTP_OK){ //獲得檔案長度 int contentLength = conn.getContentLength(); System.out.println("檔案總長度:"+contentLength); //設定想要啟動下載執行緒,用於把檔案分成多少分進行下載 RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd"); raf.setLength(contentLength); raf.close(); //假定每個執行緒負責下載的長度為1k int blockSize = 1024*2; //如果能除盡指定執行緒數 否則執行緒數+1 int size = contentLength%blockSize==0 ? contentLength/blockSize : (contentLength/blockSize)+1; for(int i = 0;i<size;i++){ if(i==(size-1)){ new DownLoadThread(i, (contentLength-(blockSize*i)), fileName,contentLength).start(); System.out.println("啟動了第:"+i+" 執行緒---------------------"+(contentLength-(blockSize*i))); return; } new DownLoadThread(i, blockSize, fileName,(i+1)*blockSize).start(); System.out.println("啟動了第:"+i+" 執行緒---------------------"+blockSize); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } class DownLoadThread extends Thread{ private int fileCount; private int blockSize; private String fileName; private int TotalLength; public DownLoadThread(int fileCount,int blockSize,String fileName,int TotalLength){ this.fileCount = fileCount; this.blockSize = blockSize; this.fileName = fileName; this.TotalLength= TotalLength; } @Override public void run() { try { URL url = new URL(ImageDownload.sate); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Range", "bytes="+(TotalLength-blockSize)+"-"+(TotalLength)); conn.connect(); System.out.println(fileCount+"開始:"+(TotalLength-blockSize)+",結束:"+TotalLength); //多執行緒同時下載檔案,因此要使用隨機訪問檔案流,即同時寫入讀取,seek(int index)制定存放的位置 RandomAccessFile raf = new RandomAccessFile(new File(fileName), "rwd"); raf.seek(TotalLength-blockSize); int code = conn.getResponseCode(); System.out.println(fileCount+">>>Code>>>"+code); if(code == HttpURLConnection.HTTP_OK || code == 206){ BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); int len = 0; byte[]buf = new byte[1024]; while((len = bis.read(buf,0,buf.length))!=-1){ raf.write(buf, 0, len); System.out.println(fileCount+"下載長度:"+len); } //回收資源 raf.close(); System.out.println("第"+fileCount+"段下載完畢!!!"); return; } System.out.println("第"+fileCount+"段下載失敗!!!"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }