如何递归搜索文件(我的自定义代码)?

时间:2016-02-11 23:34:22

标签: java recursion

我想以递归方式搜索文件。根据其他解决方案,我已经完成了很大一部分代码:

public static File[] getFiles(String path) {
    File file = new File(path);

    // Get the subdirectories.
    String[] directories = file.list(new FilenameFilter() {
       @Override
       public boolean accept(File current, String name) {
         return new File(current, name).isDirectory();
       }
    });
    for (String dir : directories) {
        // Doing recursion
    }

    // Get the files inside the directory.
    FileFilter fileFilter = new FileFilter();  
    File[] files = file.listFiles(fileFilter);

    return files;
}

FileFilter只是我的自定义过滤器。我的问题是在这种情况下我不知道如何进行递归。当然,我可以为每个子目录再次调用getFiles(),子目录路径作为参数,但不知何故必须合并返回的File数组。

有人有解决方案吗?

4 个答案:

答案 0 :(得分:2)

使用find()方法。

/* Your filter can be initialized however you need... */
YourCustomFilter filter = new YourCustomFilter(extension, maxSize);
try (Stream<Path> s = Files.find(dir, Integer.MAX_VALUE, filter::test)) {
  return s.map(Path::toFile).toArray(File[]::new);
}

这假设您的自定义过滤器有一个名为test()的方法,它接受文件及其属性;您需要稍微修改当前的文件过滤器以适应这种情况。

boolean test(Path path, BasicFileAttributes attrs) {
  ...
}

答案 1 :(得分:1)

工作示例:http://screencast.com/t/buiyV9UiEa

您可以尝试这样的事情:

//add this imports    
import java.io.File;
import java.io.FilenameFilter;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

public static File[] getFiles(String path) {
        File file = new File(path);

    // Get the subdirectories.
    String[] directories = file.list(new FilenameFilter() {
       @Override
       public boolean accept(File current, String name) {
         return new File(current, name).isDirectory();
       }
    });

    //Use a list to save the files returned from the recursive call
    List<File> filesList = new ArrayList<File>();

    if( directories != null){
        for (String dir : directories) {
            // Doing recursion
            filesList.addAll( Arrays.asList(getFiles(path + File.separator + dir)) );
        }
    }
    // Get the files inside the directory.
    FileFilter fileFilter = new FileFilter();  
    File[] files = file.listFiles(fileFilter);

    //Merge the rest of the files with the files
    //in the current dir
    if( files != null)
        filesList.addAll( Arrays.asList(files) );


    return filesList.toArray(new File[filesList.size()]);
}

代码测试和工作。希望这会有所帮助。

答案 2 :(得分:1)

import java.util.Arrays;
import java.util.ArrayList;

在初始化file之后立即设置故障安全(如果第一次呼叫路径错误)。

if (!file.isDirectory()) return new File[0];

并将代码的最后一部分更改为:

FileFilter fileFilter = new FileFilter();
ArrayList<File> files = new ArrayList(Arrays.asList(file.listFiles(fileFilter)));

for (String dir : directories) {
    files.addAll(Arrays.asList(getFiles(dir)));
}

return files.toArray(new File[0]);

toArray方法会扩展传递给它的数组(如果它太小)Ref

答案 3 :(得分:0)

你应该这样做:

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;

public static File[] getFiles(String path) {
    File file = new File(path);

    String[] directories = file.list(new FilenameFilter() {
       @Override
       public boolean accept(File current, String name) {
         return new File(current, name).isDirectory();
       }
    });

    ArrayList<File> files = Arrays.asList(file.listFiles(new FileFilter()));

    for (String dir : directories) {
        files.addAll(getFiles(dir));
    }

    return files.toArray(new File[list.size()]);
}

new File[list.size()]是必需的,否则file.toArray()会返回Object[] 此外,您应该使用lambda表达式而不是FilenameFilter,如下所示:

  String[] directories = file.list((File current, String name) -> {
      return new File(current, name).isDirectory();
  });