多线程下载

来源:互联网 发布:类似巫师3的游戏 知乎 编辑:程序博客网 时间:2024/04/29 09:01

import java.io.IOException;
import java.io.InputStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MultiThreadDownload {
    public static void main(String[] args) {
        String strUrl = "http://i7.meishichina.com/Health/UploadFiles/201109/2011092116224363.jpg";
        String strLocal = "C:\\Documents and Settings\\Administrator\\桌面\\work\\算法\\java_下载\\test.jpg";
        int threadSize = 5;
        new MultiThreadDownload().download(strUrl, strLocal, threadSize);
    }
   
    private static final int CONNECTION_TIMEOUT = 10 * 60 * 1000;
    private static final int READ_TIMEOUT = 10 * 60 * 1000;
   
    enum DownloadRet {
        DOWNLOAD_OK,
        DONWLOAD_ERROR,
    }
   
    private void download(String strUrl, String strLocal, int threadSize) {
        int tryTimeAll = 10;
        int tryTime = 0;
        while (downloadOnce(strUrl, strLocal, threadSize) != DownloadRet.DOWNLOAD_OK && tryTime < tryTimeAll) {
            System.out.println("tryTime = " + tryTime);
            tryTime++;
        }
    }
   
    private DownloadRet downloadOnce(String strUrl, String strLocal, int threadSize) {
        RandomAccessFile accessFile = null;
                   
        try {
            URL url = new URL(strUrl);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setDoInput(true);
            // 设置连接超时时间
            conn.setConnectTimeout(CONNECTION_TIMEOUT);
            // 设置读取数据超时时间
            conn.setReadTimeout(READ_TIMEOUT);
            conn.setRequestMethod("GET");
            setHeader(conn);
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                int length = conn.getContentLength();
                accessFile = new RandomAccessFile(new File(strLocal), "rwd");
                accessFile.setLength(length);
               
                // 计算每个线程负责下载的数据量
                int block = length % threadSize == 0 ? length / threadSize : length / threadSize + 1;
                for (int i = 0; i < threadSize; i++) {
                    new DownloadThread(i, block, strUrl, strLocal).start();
                }
            } else {
                return DownloadRet.DONWLOAD_ERROR;
            }
        } catch (Exception e) {
            return DownloadRet.DONWLOAD_ERROR;
       
        } finally {
            if (accessFile != null) {
                try {
                    accessFile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
       
        return DownloadRet.DOWNLOAD_OK;
    }
   
    private void setHeader(URLConnection  conn) {
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092510 Ubuntu/8.04 (hardy) Firefox/3.0.3");
        conn.setRequestProperty("Accept-Language", "en-us,en;q=0.7,zh-cn;q=0.3");
        conn.setRequestProperty("Accept-Encoding", "utf-8");
        conn.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
        conn.setRequestProperty("Keep-Alive", "300");
        conn.setRequestProperty("connnection", "keep-alive");
        conn.setRequestProperty("If-Modified-Since", "Fri, 02 Jan 2009 17:00:05 GMT");
        conn.setRequestProperty("If-None-Match", "\"1261d8-4290-df64d224\"");
        conn.setRequestProperty("Cache-conntrol", "max-age=0");
        conn.setRequestProperty("Referer", "http://www.baidu.com");
    }
   
    private class DownloadThread extends Thread {
        private int mThreadId;
        private int mBlock;
        private String mUrl;
        private String mFile;
       
        public DownloadThread(int mThreadId, int mBlock, String mUrl, String mFile) {
            this.mThreadId = mThreadId;
            this.mBlock = mBlock;
            this.mUrl = mUrl;
            this.mFile = mFile;
        }
       
        @Override
        public void run() {
            System.out.println("----thread----" + mThreadId);
            int start = mThreadId * mBlock;
            int end = (mThreadId  + 1) * mBlock - 1;
            InputStream ios = null;
            RandomAccessFile accessFile = null;
           
            try {
                accessFile = new RandomAccessFile(new File(mFile), "rwd");
                accessFile.seek(start);
                HttpURLConnection conn = (HttpURLConnection)new URL(mUrl).openConnection();
                conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
                setHeader(conn);
                if (conn.getResponseCode() == HttpURLConnection.HTTP_PARTIAL ) {
                    ios = conn.getInputStream();
                    byte[] buffer = new byte[1024];
                    int len = -1;
                   
                    while ((len = ios.read(buffer)) != -1) {
                        accessFile.write(buffer, 0, len);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (accessFile != null) {
                    try {
                        accessFile.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
               
                if (ios != null) {
                    try {
                        ios.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };
}

原创粉丝点击