java实现文件的断点续传

2022-11-13 10:11:38 java 文件 断点续传

所谓文件的断点续传,就是一个线程传输文件,另一个线程控制传输标识,以达到暂停文件效果、恢复文件上传的效果。

本demo使用最基本的线程之间的通信来实现一个简单的断点续传。

package com.test;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.io.*;
import java.NIO.ByteBuffer;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class Test {
    public static void main(String[] args) throws FileNotFoundException {
 
        File file = new File("d:\\12bb.eif");
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream("d:\\ddxc\\bqb.eif");
 
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        String fileName = file.getName();
 
        ExecutorService pool = Executors.newFixedThreadPool(30);//创建线程池,可自行定义
        Task task = new Task(true, bis, bos, fileName);
        pool.execute(task);
        Scanner scanner = new Scanner(System.in);//TODO 输入文字并敲回车,开启一个新线程控制文件的上传、暂停(在上传和暂停间来回切换)
        while (scanner.hasNextLine()) {
            String s = scanner.nextLine();
            pool.execute(task);
        }
 
 
    }
 
}
 
@Data
@AllArgsConstructor
@NoArgsConstructor
class Task implements Runnable {
 
    private volatile Boolean flag = true;//控制文件继续、暂停上传的标识,true为继续上传,false暂停上传
    private BufferedInputStream bis;
    private BufferedOutputStream bos;
    private String flagName;//监听器,一般设置为用户编号+文件名,防止不同用户上传相同为文件。但本demo只以文件名作为监听器
 
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        //TODO 对线程的后缀名进行判断,如果是不是第一个线程,则判断为控制线程
        if (!threadName.endsWith("1")) {
            this.flag = !flag;
        }
        synchronized (flagName) {
            if (!threadName.endsWith("1")) {
 
                System.out.println(threadName + "控制线程开始运行");
 
                if (flag) {
                    flagName.notifyAll();
                    System.out.println("继续传输文件");
                }
 
            } else {
 
                try {
 
                    System.out.println(threadName + "传输线程开始运行");
                    int len = 0;
                    byte[] cbuf = new byte[1024];
                    while ((len = bis.read(cbuf, 0, cbuf.length)) != -1) {
                        if (!flag) {
                            System.out.println("文件通道阻塞中");
                            flagName.wait();
                        }
                        bos.write(cbuf, 0, len);
                        bos.flush();
 
                        Thread.sleep(10);
                    }
                    System.out.println("文件传输完毕");
                    bis.close();
                    bos.close();
                    System.exit(1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println(threadName + "控制线程运行完毕");
        }
    }
}

在文件通道阻塞时,打开文件属性,观察文件大小是否停止增加。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关文章