线程---多线程复制粘贴文件夹

1.最初写的版本:
与其说是线程,其实也是递归的思路;
对于B路径中没有的文件夹、文件,不会自动创建需要我自己创建好(但new BufferedWriter(new FileWriter)应该会自动创建文件file)

import java.io.*;
import java.nio.file.Files;

/**
 * 输入两个文件夹名称,
 * 将A文件夹内容全部拷贝到B文件夹,
 * 要求使用多线程来操作。
 *
 *
 *      每进入1个文件夹  就创建1个线程复制粘贴
 */
public class FileCopy {

    public static void main(String[] args) {
        //路径不能是文件夹  必须要具体到文件
        //从里往外  先找到里面的文件
        new myTh("D:\\文件\\A","D:\\文件\\B").start();
    }
}


class myTh extends Thread{
    private String fileA;
    private String fileB;
    public myTh(String fileA, String fileB) {
        this.fileA = fileA;
        this.fileB = fileB;
    }

    @Override
    public void run() {
        File fA = new File(fileA);
        File fB = new File(fileB);

        if(!fA.exists()){
            Thread.currentThread().interrupt();//终止线程
        }
        if(fA.isDirectory()){

            File[] files = fA.listFiles();
            for (File file : files) {
                String newfA=file.getPath();

                String newpath = newfA.substring(newfA.lastIndexOf("\\"));//  \naka文件夹

                String newfB=fB.getPath()+newpath;


                System.out.println("新路径A是"+newfA+"剪出新文件路径"+newpath);
                System.out.println("新路径B是"+newfB);

                if(!newpath.contains(".")){
                    System.out.println("开始创建文件夹");
                    new File(newfB).mkdirs();
                }

                //每出现1个文件夹  开启1个线程
                new myTh(newfA,newfB).start();
            }
        }



            if(fA.isFile()) {

                if (!fB.exists()){
                    try {
                        System.out.println(fB);
                        System.out.println("开始创建文件");
                        fB.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                try (

                        FileInputStream fin = new FileInputStream(fA);
                        FileOutputStream fou = new FileOutputStream(fB)

                ) {

                    int len = -1;
                    byte[] b = new byte[1024];
                    while ((len = fin.read(b)) != -1) {
                        fou.write(b, 0, len);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    }
}

2.仅可对 文件夹【此文件夹没有子文件夹】 进行复制粘贴



import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 仅可对  文件夹【此文件夹没有子文件夹】 进行复制粘贴
 */
public class FileCopy2 {
    public static void main(String[] args) {
        //文件夹中all文件 存入List集合:
        ArrayList<File> list = new ArrayList<>();
        File f = new File("D:\\文件\\A");//需要复制的文件夹路径
        File[] files = f.listFiles();//列出文件夹中all文件

        for (int i = 0; i < files.length; i++) {

            list.add(files[i]);
        }


        FileCopy2 cp = new FileCopy2();
        CF cf = cp.new CF(list);
        RF  rf = cp.new RF(cf);



        int n = list.size();
        for(int i = 0; i < n ; i++){//有几个文件创建几个线程
            new Thread(rf).start();
        }
        System.out.println("复制完成!");
    }


    //内部类:详见*1
    class CF{
        ArrayList<File> list;//把文件存储在ArrayList集合中
        public CF(ArrayList<File> list) {
            this.list = list;
        }

        public synchronized  File getCopyFile() {//设置同步锁让每个线程获取不同的文件
            if(list.get(0) != null){
                return list.remove(0);//获得一个文件,则删除该元素,返回删除元素值,下一次再次访问第一个元素
            }
            return null;
        }
    }


    //内部类 线程:
    class RF implements Runnable{
        CF cf;//创建CF对象,内部成员变量list保存了子文件,对同一份对象进行操作
        public RF(CF cf) {
            this.cf = cf;
        }
        public void run() {
            File file = cf.getCopyFile();
            if(file == null){
                Thread.currentThread().interrupt();//终止此线程
            }
            else if(file.isFile()){
                try {
                    BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
                    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("D:\\文件\\B\\"+file.getName()));
                    String string=null;
                    while((string = bufferedReader.readLine()) != null){
                        bufferedWriter.write(string);
                        bufferedWriter.flush();
                    }
                    bufferedReader.close();
                    bufferedWriter.close();
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

3.详解:
*1 什么时候用内部类?
内部类一般用于封装。

比如可用1个类实现Runnable接口,在实现Runnable时,函数必须是
public void run(){} //注意是 public

但是,在很多时候,我们希望
这个Runnable只是在类的内部使用,即,实现一个内部线程。
(因为当类的外部也可以使用这个接口实现的功能,就存在风险)

在这种时候,使用内部类就是一个很好的选择了。

因为内部类在外部是不能实例化的!!!
这就避免了误用的可能。

你可能感兴趣的:(线程---多线程复制粘贴文件夹)