Traverse all files under a certain path and its sub-paths (recursive and non-recursive methods) + recursively copy files or folders (including all files within)

Traverse all files under a certain path and its sub-paths

  • Traversing the file tree directly and sequentially and judging whether the File object in it is a file type can be regarded as the leaf node of traversing the file tree . But due to the use of recursion , the efficiency is low .
  • If you change another method, using tree-level traversal (non-recursive, using queues ), the efficiency will be improved to a certain extent .

Method 1: Recursive method:
AllFiles class:

package com.cao.demo.allFiles;

import java.io.File;

/**
 * 作者:曹浩东
 * 使用递归遍历某一路径下的所有文件
 */
public class AllFiles {
    
    
    private int fileCount = 0;//文件计数器

    //递归遍历所有文件的方法
    public void show(String path) {
    
    
        File file = new File(path);//根据形参path实例化一个File对象
        File[] files = file.listFiles();//返回path路径下 所有文件的File对象
        //判断该目录是否为空
        if (files.length > 0) {
    
    
            //遍历该目录下的File对象
            for (int i = 0; i < files.length; i++) {
    
    
                //判断该对象是否为文件夹,如果是则递归访问
                if (files[i].isDirectory()) {
    
    
                    show(files[i].getPath());
                } else if (files[i].isFile()) {
    
    
                    //如果是该对象是文件,则打印。或者进行其他文件操作。
                    System.out.println(files[i].getPath());
                    //计数器加一
                    ++fileCount;
                }
            }
        } else {
    
    
            //如果该目录为空,则打印该目录为空
            System.out.println(path + "目录为空...");
        }
    }

    //打印文件数量的方法
    public void count() {
    
    
        if (fileCount != 0) {
    
    
            System.out.println("共扫描了" + fileCount + "个文件...");
        } else {
    
    
            System.out.println("还未进行遍历...");
        }
    }
}

Test class:

package com.cao.demo.allFiles;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        //用于计时
        long start;
        long end;
        //开始时间
        start = System.currentTimeMillis();
        //实例化AllFiles对象
        AllFiles allFiles = new AllFiles();
        //传入path参数
        allFiles.show("C:\iweb\root");
        //打印文件数量
        allFiles.count();
        //结束时间
        end = System.currentTimeMillis();
        //输出程序耗时
        System.out.println("耗时" + ((end - start) / 1000.000D) + "秒...");
    }
}

Result:
Insert picture description here
Method 2: Queue (level traversal)
allFiles class:

package com.cao.demo.allFiles2;

import java.io.File;

/**
 * 作者:曹浩东
 * 使用队列遍历某一路径下的所有文件
 */
public class AllFiles {
    
    
    private int fileCount = 0;//计数器

    public void show(String path) {
    
    
        //根据形参path实例化一个File对象
        File file = new File(path);
        //创建File类型的队列
        File[] Queue = new File[100000];
        //队头和队尾
        int front = -1, rear = -1;
        //入队
        Queue[++front] = file;
        //当队列不为空时循环
        while (front != rear) {
    
    
            //出队
            File fileInQueue = Queue[++rear];
            //判断出队的对象是否是文件
            if (fileInQueue.isFile()) {
    
    
                //是文件则打印。或者执行其他文件操作
                System.out.println(fileInQueue.getPath());
                //计数器加一
                ++fileCount;
            } else {
    
    
                //如果出队的对象是文件夹类型,则返回其下所有文件的File对象
                File[] fileIn = new File(fileInQueue.getPath()).listFiles();
                //依次入队
                for (int i = 0; i < fileIn.length; i++) {
    
    
                    Queue[++front] = fileIn[i];
                }
            }
        }
    }

    //打印文件数量的方法
    public void count() {
    
    
        if (fileCount != 0) {
    
    
            System.out.println("共扫描了" + fileCount + "个文件...");
        } else {
    
    
            System.out.println("还未进行遍历...");
        }
    }
}

Result: The
Insert picture description here
following table shows the time taken by the two methods to traverse the same folder containing 8296 files.

Recursion (post-order traversal) Queue (level traversal)
3.041 seconds 2.168 seconds

Although the degree of efficiency improvement is not as great as I imagined, method 2 is still about 30% more efficient than method 1.

Copy files or folders

  • For a folder: copy the folder to the target path in the order of traversal first
  • For files, copy directly to the target path
package com.cao.demo;

import java.io.*;

public class CopyAllFiles {
    
    
    public void copy(String src,String dst) throws IOException {
    
    
        //创建源文件的文件类型
        File srcFile=new File(src);
        //如果是文件夹
        if(srcFile.isDirectory()){
    
    
            //创建目标路径+待复制文件夹名对象
            File file=new File(dst+"\\"+srcFile.getName());
            //创建该文件夹
            file.mkdir();
            //生成源目录下的所有文件或文件夹的文件对象
            File[] allFiles=srcFile.listFiles();
            //在文件夹不为空的情况下
            if(allFiles.length>0){
    
    
                //遍历源文件夹下的文件或文件夹对象
                for (int i = 0; i < allFiles.length; i++) {
    
    
                    //递归调用
                    copy(allFiles[i].getPath(),file.getPath());
                }
            }
        }else if(srcFile.isFile()){
    
    
            FileInputStream fileInputStream=new FileInputStream(src);
            FileOutputStream fileOutputStream=new FileOutputStream(dst+"\\"+srcFile.getName());
            byte[] buff=new byte[1024];
            int len;
            while((len=fileInputStream.read(buff))!=-1){
    
    
                fileOutputStream.write(buff,0,len);
                fileOutputStream.flush();
            }
            fileInputStream.close();
            fileOutputStream.close();
        }
    }

    public static void main(String[] args) throws IOException {
    
    
        CopyAllFiles copyAllFiles=new CopyAllFiles();
        copyAllFiles.copy("C:\\iweb\\1","C:\\iweb\\copy");
    }
}

Guess you like

Origin blog.csdn.net/qq_44371305/article/details/113653556