天天看点

java_实现目录拷贝,同时显示复制的进度(用当前复制的文件夹容量/源文件夹总容量来表示)

package experiment11.exp1;

import experiment9.FileName;

import java.io.File;
import java.io.IOException;

/**
 * 1、	实现目录拷贝,同时显示复制的进度。   可用一个线程复制文件夹,另一个线程显示复制的进度。									
 * 进度的表示是用当前复制的文件夹容量/源文件夹总容量来表示。*/


import static experiment11.exp1.CopyDir.copyDir;
import static java.lang.Thread.sleep;

public class CopyRate {
    // Scanner scanner = new Scanner(System.in);
    //System.out.println("输入被复制源目录名:");
    static String sourceDirectory = FileName.fileName11_1;
    static File sourceFile = new File(sourceDirectory);

    //System.out.println("输入副本目标目录名");
    public static String destinationDirectory = "d:/a";//D:\a scanner.nextLine();
    static File nowFile = new File(destinationDirectory);

    public static void main(String[] args) throws InterruptedException {

        // 源目录的大小(容量)
        long sourceFileSize = sourceFile.length();//由于main方法是static的,所有不能想非static的方法那样直接访问非static变量。(偷懒的话就将这些成员变量设为static了。

        // 打印执行比率的线程:
        Thread PrintRateThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    //some wrong usages of File.length() method.
//                    System.out.println(String.format("已经复制:" + ((double)nowFile.length() / sourceFileSize)));
                    // System.out.println("已经复制:" + nowFile.length());
                    try {
                        Thread.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    long sizeDestination = CountDirSize.getCountSize(destinationDirectory),
                            sizeSource = CountDirSize.getCountSize(sourceDirectory);
                    double completionRate = sizeDestination * 1.0 / sizeSource;
                    System.out.printf("当前复制完成比:%.2f%%\n" ,100*completionRate);

                  /*  if ( completionRate == 1) {
                        break;
                    }*/
                /*    if (sizeDestination==sizeSource){
                        System.out.println(sizeDestination==sizeSource);
                        break;
                    }*/
                    if(Thread.currentThread().isInterrupted()){
                        System.out.printf("当前复制完成比:%.2f%%\n" ,100.00);
                        System.out.println("文件夹复制完成");
                        break;
                    }

                }
            }
        });//endThreadPrint
        Thread copyTread = new Thread(new Runnable() {
            @Override
            public void run() {
                {
                    try {
                        copyDir(sourceDirectory, destinationDirectory);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    PrintRateThread.interrupt();
                }
            }
        });//end copyThread
        //start the two threads:
        copyTread.start();
        PrintRateThread.start();
    }//endMain


}


           
package experiment11.exp1;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

/**
 * @Author xuchaoxin
 * @Date 12/18/2020 9:00 PM
 * @Version 1.0
 */
public class CopyDir {
    /*本递归复制函数具有检查并创建新目录的能力,*/
    static void copyDir(String oldPath, String newPath) throws IOException {
        File file = new File(oldPath);
        String[] filePath = file.list();
        if (!(new File(newPath)).exists()) {
            (new File(newPath)).mkdir();//创建目录
        }

        for (String x : filePath) {
            /*如果这(x)是一个子目录:(执行递归)*/
//            if ((new File(oldPath + File.separator + x)).isDirectory()) {
            //内部嵌套线程,又涉及到何时结束所有线程的问题
//                Thread threadDelay = new Thread(new Runnable() {
//                    @Override
//                    public void run() {
//                        /*这里的sleep不是和有用*/
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
//                        try {
//                            copyDir(oldPath + File.separator + x, newPath + File.separator + x);
//                            //System.out.println("copying...");
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                });
//                threadDelay.start();
//            }//end if
        /*这里仅采用单线程复制:(单线程也可设置sleep)*/
            if ((new File(oldPath + File.separator + x)).isDirectory()) {
                try {
                    copyDir(oldPath + File.separator + x, newPath + File.separator + x);
                    //System.out.println("copying...");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
/*            */
            /**
             * 在这里拖延时间(不让目录过快的拷贝完).
             */
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //System.out.println(CountDirSize.getCountSize(newPath));//检测目标目录的大小

            /*如果x所指的是个文件:执行复制即可*/
            if (new File(oldPath + File.separator + x).isFile()) {
                File source = new File(oldPath + File.separator + x);
                File dest = new File(newPath + File.separator + x);
                if (!(dest.exists())) {
                    Files.copy(source.toPath(), dest.toPath());//创建新文件的能力
                }

            }
        }//endFor
        //System.out.println("The replication operation has been successfully executed!");
    }//endCopyFunction
}

           
package experiment11.exp1;

import experiment9.FileName;

import java.io.File;
import java.io.IOException;

/**
 * @Author xuchaoxin
 * @Date 12/18/2020 9:10 PM
 * @Version 1.0
 */
public class CountDirSize {
    static long countSize = 0;

    /**
     * 该函数以绝对路径名字符串path为参数进行处理,注意,path所指的是dir还是file不需要知道(由函数进行分析即可)
     * @param path
     * @return
     */
    static void countDirSize(String path) {
        File pathFile = new File(path);
        String[] list = pathFile.list();
        if (pathFile.isDirectory()) {
            for (String items : list) {
                String subItem=path+File.separator+items;
                //递归调用.
                countDirSize(subItem);
            }
        } else {
            //this is a file.
            countSize += pathFile.length();//返回文件字节数(无法直接正确作用于文件夹)
            /**
             * Returns:
             * The length, in bytes, of the file denoted by this abstract pathname, or 0L if the file does not exist. Some operating systems may return 0L for pathnames denoting system-dependent entities such as devices or pipes.
             */
        }
        //return countSize;
    }

    public static long getCountSize(String path) {
        countDirSize(path);
        return countSize;
    }


    /*test the function:(it's ok)*/
    public static void main(String[] args) {
        System.out.println(getCountSize(FileName.fileName11_1));
    }
}