我如何递归地列出在Java目录下的所有文件?框架是否提供任何实用程序?
我看到了很多俗气的实现。但没有来自框架或nio
我如何递归地列出在Java目录下的所有文件?框架是否提供任何实用程序?
我看到了很多俗气的实现。但没有来自框架或nio
当前回答
公认的答案是很好的,但是当你想在lambda中执行IO时,它就崩溃了。
如果你的action声明了IOExceptions,你可以这样做。
您可以将过滤后的流视为Iterable,然后在常规的for-each循环中执行操作。这样,就不必在lambda中处理异常。
try (Stream<Path> pathStream = Files.walk(Paths.get(path))
.filter(Files::isRegularFile)) {
for (Path file : (Iterable<Path>) pathStream::iterator) {
// something that throws IOException
Files.copy(file, System.out);
}
}
在这里找到诀窍:https://stackoverflow.com/a/32668807/1207791
其他回答
我的建议是:
public void list(File file) {
System.out.println(file.getName());
File[] children = file.listFiles();
for (File child : children) {
list(child);
}
}
System.out.println只是用来指示对该文件执行一些操作。没有必要区分文件和目录,因为一个正常的文件只会有零个子文件。
除了递归遍历,还可以使用基于访问者的方法。
下面的代码是使用基于访问者的遍历方法。我们期望程序的输入是要遍历的根目录。
public interface Visitor {
void visit(DirElement d);
void visit(FileElement f);
}
public abstract class Element {
protected File rootPath;
abstract void accept(Visitor v);
@Override
public String toString() {
return rootPath.getAbsolutePath();
}
}
public class FileElement extends Element {
FileElement(final String path) {
rootPath = new File(path);
}
@Override
void accept(final Visitor v) {
v.visit(this);
}
}
public class DirElement extends Element implements Iterable<Element> {
private final List<Element> elemList;
DirElement(final String path) {
elemList = new ArrayList<Element>();
rootPath = new File(path);
for (File f : rootPath.listFiles()) {
if (f.isDirectory()) {
elemList.add(new DirElement(f.getAbsolutePath()));
} else if (f.isFile()) {
elemList.add(new FileElement(f.getAbsolutePath()));
}
}
}
@Override
void accept(final Visitor v) {
v.visit(this);
}
public Iterator<Element> iterator() {
return elemList.iterator();
}
}
public class ElementWalker {
private final String rootDir;
ElementWalker(final String dir) {
rootDir = dir;
}
private void traverse() {
Element d = new DirElement(rootDir);
d.accept(new Walker());
}
public static void main(final String[] args) {
ElementWalker t = new ElementWalker("C:\\temp");
t.traverse();
}
private class Walker implements Visitor {
public void visit(final DirElement d) {
System.out.println(d);
for(Element e:d) {
e.accept(this);
}
}
public void visit(final FileElement f) {
System.out.println(f);
}
}
}
公认的答案是很好的,但是当你想在lambda中执行IO时,它就崩溃了。
如果你的action声明了IOExceptions,你可以这样做。
您可以将过滤后的流视为Iterable,然后在常规的for-each循环中执行操作。这样,就不必在lambda中处理异常。
try (Stream<Path> pathStream = Files.walk(Paths.get(path))
.filter(Files::isRegularFile)) {
for (Path file : (Iterable<Path>) pathStream::iterator) {
// something that throws IOException
Files.copy(file, System.out);
}
}
在这里找到诀窍:https://stackoverflow.com/a/32668807/1207791
即使有人已经提供了Java 8 walk,您也可以这样做。
它将递归地为您提供所有文件
private Stream<File> files(File file) {
return file.isDirectory()
? Arrays.stream(file.listFiles()).flatMap(this::files)
: Stream.of(file);
}
你自己用简单的递归来写:
public List<File> addFiles(List<File> files, File dir)
{
if (files == null)
files = new LinkedList<File>();
if (!dir.isDirectory())
{
files.add(dir);
return files;
}
for (File file : dir.listFiles())
addFiles(files, file);
return files;
}