Java-->多线程断点续传
--> 在多线程复制的基础上加入断点续传的功能
-->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 }