--> 在多線程復制的基礎上加入斷點續傳的功能
-->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 }