我如何递归地列出在Java目录下的所有文件?框架是否提供任何实用程序?
我看到了很多俗气的实现。但没有来自框架或nio
我如何递归地列出在Java目录下的所有文件?框架是否提供任何实用程序?
我看到了很多俗气的实现。但没有来自框架或nio
当前回答
不需要外部库。 返回一个集合,这样你就可以在调用后对它做任何你想做的事情。
public static Collection<File> listFileTree(File dir) {
Set<File> fileTree = new HashSet<File>();
if(dir==null||dir.listFiles()==null){
return fileTree;
}
for (File entry : dir.listFiles()) {
if (entry.isFile()) fileTree.add(entry);
else fileTree.addAll(listFileTree(entry));
}
return fileTree;
}
其他回答
FileUtils有iterateFiles和listFiles方法。试一试吧。(从commons-io)
编辑:您可以在这里查看不同方法的基准测试。common -io方法似乎很慢,所以从这里选择一些更快的方法(如果重要的话)
public static String getExten(String path) {
int i = path.lastIndexOf('.');
if (i > 0) {
return path.substring(i);
}
else return "";
}
public static List<String> GetAllFiles(String path, List<String>fileList){
File file = new File(path);
File[] files = file.listFiles();
for(File folder:files) {
if(extensions.contains(getExten(folder.getPath()))) {
fileList.add(folder.getPath());
}
}
File[] direcs = file.listFiles(File::isDirectory);
for(File dir:direcs) {
GetAllFiles(dir.getPath(),fileList);
}
return fileList;
}
这是一个简单的递归函数,应该会提供所有文件。Extensions是一个字符串列表,它只包含那些被接受的扩展名。例如扩展名= [".txt",".docx"]等。
我的版本(当然我可以在Java 8中使用内置的walk;-)):
public static List<File> findFilesIn(File rootDir, Predicate<File> predicate) {
ArrayList<File> collected = new ArrayList<>();
walk(rootDir, predicate, collected);
return collected;
}
private static void walk(File dir, Predicate<File> filterFunction, List<File> collected) {
Stream.of(listOnlyWhenDirectory(dir))
.forEach(file -> walk(file, filterFunction, addAndReturn(collected, file, filterFunction)));
}
private static File[] listOnlyWhenDirectory(File dir) {
return dir.isDirectory() ? dir.listFiles() : new File[]{};
}
private static List<File> addAndReturn(List<File> files, File toAdd, Predicate<File> filterFunction) {
if (filterFunction.test(toAdd)) {
files.add(toAdd);
}
return files;
}
我认为这应该是可行的:
File dir = new File(dirname);
String[] files = dir.list();
这样你就有文件和dirs了。现在使用递归并对dirs(文件类具有isDirectory()方法)执行相同的操作。
接受的答案很差,因为它可能导致资源泄漏。
文件。walk由DirectoryStreams支持。
返回的流封装了一个或多个directorystream。如果需要及时处理文件系统资源,则应该使用try-with-resources构造来确保在流操作完成后调用流的close方法。对关闭的流进行操作将导致IllegalStateException异常。
DirectoryStream必须在它的javadoc中指定关闭:
DirectoryStream在创建时打开,并通过调用close方法关闭。关闭目录流将释放与该流关联的所有资源。关闭流失败可能导致资源泄漏。try-with-resources语句提供了一个有用的结构来确保流是关闭的:
Path dir = ...
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
for (Path entry: stream) {
...
}
}
因此,正确的答案是:
try (Stream<Path> stream = Files.walk(Paths.get(path))) {
// Do something with the stream.
stream.filter(Files::isRegularFile)
.forEach(System.out::println);
}