--> 在多線程復制的基礎上加入斷點續傳的功能
-->Test 測試類
1 package com.dragon.java.multithreaddownload; 2 3 import java.io.File; 4 5 /* 6 * 多線程斷點續傳(下載) 7 */ 8 public class Test { 9 public static void main(String[] args) { 10 // @SuppressWarnings("resource") 11 // Scanner scanner = new Scanner(System.in); 12 // System.out.println("請輸入文件路徑:"); 13 // 直接寫死文件和線程數.. 14 File srcFile = new File("F:/mp4/01_Java.mp4"); 15 // System.out.println("請輸入線程數:"); 16 // int n = scanner.nextInt(); 17 int n = 4; 18 if (!srcFile.exists()) { 19 System.out.println("該文件不存在!"); 20 } 21 22 File desFile = new File(srcFile.getParent(), "new" + srcFile.getName()); 23 24 // 單線程復制長度 25 long partLenghth = srcFile.length() / n + 1; 26 for (int i = 1; i < n + 1; i++) { 27 // 啟動線程 28 new MyThread(srcFile, desFile, partLenghth * (i - 1), partLenghth 29 * i).start(); 30 31 } 32 } 33 }
--> MyThread 線程實現類
1 package com.dragon.java.multithreaddownload; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.RandomAccessFile; 6 7 public class MyThread extends Thread { 8 private File srcFile; 9 private File desFile; 10 private long start; 11 private long end; 12 13 MyThread() { 14 super(); 15 } 16 17 MyThread(File srcFile, File desFile, long start, long end) { 18 super(); 19 this.srcFile = srcFile; 20 this.desFile = desFile; 21 this.start = start; 22 this.end = end; 23 } 24 25 @Override 26 public void run() { 27 // 創建配置文件存儲中斷時的文件指針 28 File configFile = new File(desFile.getParent(), Thread.currentThread() 29 .getId() + ".config"); 30 if (!configFile.exists() && desFile.exists()) { 31 32 System.out.println(Thread.currentThread().getName() + "已經完成了下載"); 33 return; 34 } 35 // 將流寫在try() 中可以不需手動關閉流 36 try (RandomAccessFile rafSrc = new RandomAccessFile(srcFile, "r"); 37 RandomAccessFile rafDes = new RandomAccessFile(desFile, "rw"); 38 RandomAccessFile rafConfig = new RandomAccessFile(configFile, 39 "rw");) { 40 41 rafConfig.setLength(8); 42 43 // 當不是第一次下載時,將配置文件中的指針傳遞給開始指針 44 long pointer = rafConfig.readLong(); 45 if (pointer != 0) { 46 start = pointer; 47 } 48 rafSrc.seek(start); 49 rafDes.seek(start); 50 51 // 顯示完成度 System.out.println(Thread.currentThread().getName() + "已下載:" 52 + ((float) pointer / srcFile.length()) * 100 + "%"); 53 54 int len = -1; 55 byte[] buffer = new byte[32]; 56 while ((len = rafSrc.read(buffer)) != -1) { 57 rafDes.write(buffer, 0, len); 58 pointer = rafSrc.getFilePointer(); 59 rafConfig.seek(0); 60 rafConfig.writeLong(pointer); 61 // 當每個線程完成任務時結束線程 62 if (rafSrc.getFilePointer() >= end) { 63 break; 64 } 65 } 66 } catch (IOException e) { 67 System.out.println(e); 68 } 69 // 刪除配置文件 70 configFile.delete(); 71 } 72 }