我想以递归方式搜索文件。根据其他解决方案,我已经完成了很大一部分代码:
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数组。
有人有解决方案吗?
答案 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();
});