简体   繁体   English

Java - 遍历目录中的所有文件

[英]Java - Iterate over all files in directory

I want to find all the txt files in directory and in the nested sub-directories. 我想在目录和嵌套子目录中找到所有txt文件。 If found, I want to move that from one location to another. 如果找到,我想将其从一个位置移动到另一个位置。

The below code works fine, if i don't have any nested sub-directories. 如果我没有任何嵌套的子目录,下面的代码工作正常。

The problem with the below code is, Once it find the nested directories it return the file only from that particular nested sub-directory. 下面代码的问题是,一旦找到嵌套目录,它只返回该特定嵌套子目录中的文件。 But I want all the txt files in my directory ( parent and its nested sub-directories ). 但我想要我的目录中的所有txt文件(父和它的嵌套子目录)。

public class FilesFindingInDirectory {
    static ArrayList<File> al = new ArrayList<File>();
    static File fileLocation = null;
    public static void main(String[] args) throws IOException {


        File filePath = new File("C:\\Users\\Downloads");

        File[] listingAllFiles = filePath.listFiles();

        ArrayList<File> allFiles = iterateOverFiles(listingAllFiles);


                for (File file : allFiles) {
                    if(file != null) {
                        String fileName = file.getName();

                        String sourceFilepath = file.getAbsolutePath();
                        File targetFilePath = new File("D:\\TestFiles");
                        String targetPath = targetFilePath.getPath();

                        Files.move(Paths.get(sourceFilepath), Paths.get("D:\\TestFiles\\" + fileName)); 
                    }

                }
            }


public static ArrayList<File> iterateOverFiles(File[] files) {


        for (File file : files) {

            if (file.isDirectory()) {

                iterateOverFiles(file.listFiles());// Calls same method again.

            } else {

                fileLocation = findFileswithTxtExtension(file);
                if(fileLocation != null) {
                    System.out.println(fileLocation);
                    al.add(fileLocation);
                }


            }
        }

        return al;
    }

public static File findFileswithTxtExtension(File file) {

        if(file.getName().toLowerCase().endsWith("txt")) {
            return file;
        }

        return null;
    }
}

You're already using the nio Files API to move the files, why not using it to iterate over the files? 您已经在使用nio Files API移动文件,为什么不使用它来迭代文件?

 List<Path> txtFiles = Files.walk(Paths.get("C:\\Users\\Downloads"))
                            //use to string here, otherwise checking for path segments
                            .filter(p -> p.toString().endsWith(".txt"))
                            .collect(Collectors.toList());

If you don't need that intermediary list, you could as well run your move operation in a foreach terminal operation 如果您不需要该中间列表,您也可以在foreach终端操作中运行您的移动操作

Files.walk(Paths.get("C:\\Users\\Downloads"))
     .filter(p -> p.toString().endsWith(".txt"))
     .forEach(p -> {
        try {
            Files.move(p, Paths.get("D:\\TestFiles", p.getFileName().toString()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    });

From your recursive function remove this line: 从您的递归函数中删除此行:

return al;

change this line to just call the recursive function: 将此行更改为只调用递归函数:

ArrayList<File> allFiles = iterateOverFiles(listingAllFiles);

to

iterateOverFiles(listingAllFiles);

and finally change your for loop to iterate over the static field al. 最后改变你的for循环迭代静态字段al。

for (File file : allFiles) {

to

for (File file : al) {

Explanation: There are numerous ways to write recursion for this problem. 说明:有许多方法可以为此问题编写递归。 In this case you have a global variable for collecting the results. 在这种情况下,您有一个用于收集结果的全局变量。 Each iteration should add to that global result, and simply return. 每次迭代都应该添加到该全局结果中,然后返回。 At the end of all recursion calls, the global variable will contain all the results. 在所有递归调用结束时,全局变量将包含所有结果。

You are properly calling the function recursively, but you're then ignoring its return value. 您正在以递归方式正确调用该函数,但是您忽略了它的返回值。 Instead, you should append it to the result list: 相反,您应该将其附加到结果列表:

public static List<File> iterateOverFiles(File[] files) {
    List<File> result = new ArrayList<>();
    for (File file : files) {
        if (file.isDirectory()) {
            result.addAll(iterateOverFiles(file.listFiles()); // Here!
        } else {
            fileLocation = findFileswithTxtExtension(file);
            if(fileLocation != null) {
                result.add(fileLocation);
            }
        }
    }

    return result;
}

Just iterate over a directory, skipping any non-directory entries and entries that do not have the desired extension. 只需遍历目录,跳过任何非目录条目和没有所需扩展名的条目。 Add all files with the correct extension to a result, and do that recursively for each directory. 将具有正确扩展名的所有文件添加到结果中,并以递归方式为每个目录执行此操作。

public class FilesFindingInDirectory {
   public static void main(String[] args) throws IOException {


    File filePath = new File("C:\\Users\\Downloads");


    Collection<File> allFiles = findFiles(filePath, ".txt");
    allFiles.forEach(file -> {
                    String fileName = file.getName();

                    String sourceFilepath = file.getAbsolutePath();
                    File targetFilePath = new File("D:\\TestFiles");
                    String targetPath = targetFilePath.getPath();

                    Files.move(Paths.get(sourceFilepath), Paths.get("D:\\TestFiles\\" + fileName)); 
                }

            }
        }

public static List<File> findFiles(File dir, String extension) {
    File[] files = dir.listFiles(f -> f.isDirectory() || f.getName().toLowerCase().endsWith(extension);
    ArrayList<File> result = new ArrayList<>();  
    if (files != null) {
       for (File file : files) {

        if (file.isDirectory()) {
            result.addAll(findFiles(file, extension);
        } else {
            result.add(file);
        }

    }

    return result;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM