Java之多線程斷點下載的實現

來源:互聯網
上載者:User

標籤:下載   模式   多線程   斷點   

RandomAccessFile類:
此類的執行個體支援對隨機訪問檔案的讀取和寫入。隨機訪問檔案的行為類似儲存在檔案系統中的一個大型 byte 數組。存在指向該隱含數組,游標或索引,稱為檔案指標;輸入操作從檔案指標開始讀取位元組,並隨著對位元組的讀取而前移此檔案指標。如果隨機訪問檔案以讀取/寫入模式建立,則輸出操作也可用;輸出操作從檔案指標開始寫入位元組,並隨著對位元組的寫入而前移此檔案指標。寫入隱含數組的當前末尾之後的輸出操作導致該數組擴充。該檔案指標可以通過 getFilePointer 方法讀取,並通過 seek 方法設定。

下面有RandomAccessFile實現安卓下的斷點下載的demo。
伺服器端可以用tomcat類比,將被下載的測試檔案放入webApp/ROOT目錄下即可。
先給出java藉助HttpURLConnection類實現的多線程下載代碼:

public class MultiThread {    private static int threadCount = 3;    private static long blockSize;    private static int runningThreadCount;    public static void main(String[] args) throws Exception {        String path = "http://10.0.67.172/test.exe";        URL url = new URL(path);         HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setRequestMethod("GET");        conn.setConnectTimeout(5000);//逾時時間        int code = conn.getResponseCode();        System.out.println(code);        if(code / 100 == 2){            int size = conn.getContentLength();//擷取資源檔的長度            System.out.println("請求資源大小:" + size);            blockSize = size / threadCount;//將資源檔分為多少塊,沒一塊的大小            runningThreadCount = threadCount;            long startIndex = 0;            long endIndex = 0;            //開啟若干個子線程去實現多線程的下載            for(int i = 0; i < threadCount; i++){                startIndex = i * blockSize;                endIndex = (i + 1) * blockSize - 1;                if(i == threadCount-1){                    endIndex = size - 1;                }                System.out.println("開啟線程:" + i + ";" + "開始位置:" + startIndex + ":" + "結束位置:" + endIndex);                new DownThread(path, startIndex, endIndex, i).start();            }        }    }    private static class DownThread extends Thread{        private String path;        private long startIndex;        private long endIndex;        private int threadId;        public DownThread(String path, long startIndex, long endIndex, int threadId) {            super();            this.path = path;            this.startIndex = startIndex;            this.endIndex = endIndex;            this.threadId = threadId;        }        @Override        public void run() {            try {                URL url = new URL(path);                HttpURLConnection conn = (HttpURLConnection) url.openConnection();                conn.setRequestMethod("GET");                conn.setReadTimeout(5000);                conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);//設定伺服器上的檔案的讀取位置                int code = conn.getResponseCode();                if(code / 100 == 2){                    InputStream is = conn.getInputStream();                    File file = new File("temp.exe");                    RandomAccessFile raf = new RandomAccessFile(file, "rw");                    raf.seek(startIndex);                    System.out.println("第" + threadId + "個檔案的開始位置:" + String.valueOf(startIndex));                    int len = 0;                    byte[] buffer = new byte[1024];                    while ((len = is.read(buffer)) != -1){                        raf.write(buffer, 0, len);//寫檔案                    }                    raf.close();                }            } catch (Exception e) {                e.printStackTrace();            }        }    }}

斷點下載的原理就是將上次檔案下載的位置儲存為臨時檔案,當完全下載完畢時再刪除。

public class MultiThread {    private static int threadCount = 3;    private static long blockSize;    private static int runningThreadCount;    public static void main(String[] args) throws Exception {        String path = "http://10.0.67.172/test.rar";        URL url = new URL(path);         HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setRequestMethod("GET");        conn.setConnectTimeout(5000);//逾時時間        int code = conn.getResponseCode();        System.out.println(code);        if(code / 100 == 2){            int size = conn.getContentLength();//擷取資源檔的長度            System.out.println("請求資源大小:" + size);            blockSize = size / threadCount;//將資源檔分為多少塊,沒一塊的大小            runningThreadCount = threadCount;            long startIndex = 0;            long endIndex = 0;            for(int i = 0; i < threadCount; i++){                startIndex = i * blockSize;                endIndex = (i + 1) * blockSize - 1;                if(i == threadCount-1){                    endIndex = size - 1;                }                System.out.println("開啟線程:" + i + ";" + "開始位置:" + startIndex + ":" + "結束位置:" + endIndex);                new DownThread(path, startIndex, endIndex, i).start();            }        }    }    private static class DownThread extends Thread{        private String path;        private long startIndex;        private long endIndex;        private int threadId;        public DownThread(String path, long startIndex, long endIndex, int threadId) {            super();            this.path = path;            this.startIndex = startIndex;            this.endIndex = endIndex;            this.threadId = threadId;        }        @Override        public void run() {            int total = 0;            try {                File positionFile = new File(threadId + ".txt");                URL url = new URL(path);                HttpURLConnection conn = (HttpURLConnection) url.openConnection();                conn.setRequestMethod("GET");                //接著上次的檔案繼續下載                if(positionFile.exists() && positionFile.length() > 0){                    FileInputStream fis = new FileInputStream(positionFile);                    BufferedReader reader = new BufferedReader(new InputStreamReader(fis));                    //擷取當前線程上次下載的總大小是多少                    String lasttotalstr = reader.readLine();                    int lastTotal = Integer.valueOf(lasttotalstr);                    System.out.println("上次線程下載的總大小:" + lastTotal);                    startIndex += lastTotal;                    total += lastTotal;                    fis.close();                }                conn.setReadTimeout(5000);                conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);//設定伺服器上的檔案的讀取位置                int code = conn.getResponseCode();                if(code / 100 == 2){                    InputStream is = conn.getInputStream();                    File file = new File("temp.rar");                    RandomAccessFile raf = new RandomAccessFile(file, "rw");                    raf.seek(startIndex);                    System.out.println("第" + threadId + "個檔案的開始位置:" + String.valueOf(startIndex));                    int len = 0;                    byte[] buffer = new byte[1024];                    while ((len = is.read(buffer)) != -1){                        RandomAccessFile rf = new RandomAccessFile(positionFile, "rwd");                        raf.write(buffer, 0, len);//寫檔案                        total += len;                        rf.write(String.valueOf(total).getBytes());                        rf.close();                    }                    is.close();                    raf.close();                }            } catch (Exception e) {                e.printStackTrace();            }finally{                synchronized (DownThread.class) {                    System.out.println("線程" + threadId + "下載完畢了");                    runningThreadCount--;                    if (runningThreadCount < 1) {                        System.out.println("所有的線程都工作完畢了。刪除臨時記錄的檔案");                        for (int i = 0; i < threadCount; i++) {                            File f = new File(i + ".txt");                            System.out.println(f.delete());                        }                    }                }            }        }    }}

運行結果:

Java之多線程斷點下載的實現

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.