1. 程式人生 > >HttpURLConnection方法之setRequestProperty()淺談

HttpURLConnection方法之setRequestProperty()淺談

【問題】關於從網上下載一個檔案分多個執行緒同時下載。

主要使用到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();
            }
    }
}