使用聲明:
類名:MultiThreadDownloadUtil
API:
(1)download(String path,int count);
path:文件URL;
count:線程數量;
- package org.xiazdong.multidownload.util;
-
- import java.io.File;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.URL;
-
-
- public class MultiThreadDownloadUtil{
- private static int filesize;
- private static int block;
- private static String filename;
- private static int downloadsize;
- private class MyThread extends Thread{
- private int i; //線程ID
- private String path; //下載文件的URL
-
- public MyThread(int i, String path) {
- this.i = i;
- this.path = path;
- downloadsize = 0;
- }
- @Override
- public void run() {
- try{
- System.out.println("線程"+(i+1)+"開始下載");
- //1.打開文件,並定位位置
- RandomAccessFile raf = new RandomAccessFile(new File(filename), "rwd");
- raf.seek(i*block); //定位到此線程要負責下載的位置
- int start = i*block;
- int end = (i+1)*block-1;
- //2.連接服務器
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
- conn.setRequestProperty("range", "bytes="+start+"-"+end); //發出請求頭
-
- if(conn.getResponseCode()==206){ //注意:分段下載的返回碼為206,而不是200
- InputStream in = conn.getInputStream();
- int length = 0;
- byte[]data = new byte[1024];
- while((length=in.read(data))!=-1){
- raf.write(data,0,length); //寫入本地文件
- }
- }
- //顯示下載進度
- downloadsize += (end-start);
- System.out.println("已下載"+downloadsize/1024.0+"k,共"+filesize/1024.0+"k");
- //3.關閉文件
- raf.close();
- System.out.println("線程"+(i+1)+"結束下載...");
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- }
- /**
- * 下載文件
- * @param path URL
- * @param threadcount 線程數
- * @throws Exception
- */
- public static void download(String path,int threadcount) throws Exception{
- filename = path.substring(path.lastIndexOf('/')+1);
- filesize = getFileSize(path);
- block = getBlockSize(filesize,threadcount);
- createLocalRandomFile(filesize);
- MultiThreadDownloadUtil mdu = new MultiThreadDownloadUtil();
- for(int i=0;i<threadcount;i++){
- mdu.new MyThread(i,path).start();
- }
- }
- /**
- * 創建一個本地文件,並設置文件的大小
- * @param filesize
- * @throws Exception
- */
- private static void createLocalRandomFile(int filesize) throws Exception {
- RandomAccessFile raf = new RandomAccessFile(new File(filename), "rwd");
- raf.setLength(filesize);
- raf.close();
- }
- /**
- * 根據文件總大小和線程數求出每個線程要下載的數據量
- * @param filesize
- * @param threadcount
- * @return
- */
- private static int getBlockSize(int filesize, int threadcount) {
- return filesize%threadcount==0?filesize/threadcount:(filesize/threadcount+1);
- }
- /**
- * 求出文件總大小
- * @param path
- * @return
- * @throws Exception
- */
- private static int getFileSize(String path) throws Exception{
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("GET");
- if(conn.getResponseCode()==200){
- return conn.getContentLength();
- }
- else{
- return 0;
- }
- }
- }
測試類:
- package org.xiazdong.download;
-
- import org.xiazdong.multidownload.util.MultiThreadDownloadUtil;
-
-
- public class MultiThreadDownloader {
-
- public static void main(String[] args) throws Exception {
- int threadCount = 3; //指定線程數量
- String path = "http://dlc2.pconline.com.cn/filedown_61761_6694063/drivethelife2010_pconline_setup.exe"; //指定下載文件路徑
- MultiThreadDownloadUtil.download(path, threadCount);
- }
- }
將此文件下載到工程目錄後,運行可用;