特定のパスとそのサブパス(再帰的および非再帰的メソッド)の下にあるすべてのファイルをトラバースし、ファイルまたはフォルダー(内のすべてのファイルを含む)を再帰的にコピーします

特定のパスとそのサブパスの下にあるすべてのファイルをトラバースします

  • ファイルツリーを直接かつ順次にトラバースし、その中のFileオブジェクトがファイルタイプであるかどうかを判断することは、ファイルツリーをトラバースするリーフノードと見なすことができますただし、再帰を使用しているため効率は低くなります。
  • ツリーレベルのトラバーサル(非再帰的、キューを使用を使用して別の方法を変更すると効率がある程度向上します。

メソッド1:再帰メソッド:
AllFilesクラス:

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("还未进行遍历...");
        }
    }
}

テストクラス:

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) + "秒...");
    }
}

結果:
ここに画像の説明を挿入
方法2:キュー(レベルトラバーサル)
allFilesクラス:

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("还未进行遍历...");
        }
    }
}

結果:
ここに画像の説明を挿入
次の表は、2つの方法が8296ファイルを含む同じフォルダーをトラバースするのにかかる時間を示しています。

再帰(注文後のトラバーサル) キュー(レベルトラバーサル)
3.041秒 2.168秒

効率の向上の程度は私が想像したほど大きくはありませんが、方法2は方法1よりも約30%効率的です。

ファイルまたはフォルダをコピーする

  • フォルダの場合:最初にトラバーサルの順序でフォルダをターゲットパスにコピーします
  • ファイルの場合は、ターゲットパスに直接コピーします
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");
    }
}

おすすめ

転載: blog.csdn.net/qq_44371305/article/details/113653556