Files.list和Files.walkFileTree和Files.walk有什么区别,maxdepth = 1?

时间:2016-06-16 11:38:28

标签: java nio2 java.nio.file

如果我只想在目录的第一级对文件执行某些操作, 使用Files.list(...)Files.walkFileTree(...)Files.walk(...)

之间有区别吗?
Files.walkFileTree(directory, Collections.emptySet(), 1, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        doSomething(file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        // log exc
        return FileVisitResult.CONTINUE;
    }
});

Files.list(directory)
    .forEach(path -> {
        try {
            doSomething(path);
        } catch (IOException exc) {
            // log exc
        }
    });

Files.walk(directory, 1)
    .forEach(path -> {
        try {
            doSomething(path);
        } catch (IOException exc) {
            // log exc
        }
});

3 个答案:

答案 0 :(得分:7)

使用以下代码作为测试,我解决了这个问题。 walk*list之间的主要区别在于list(dir)在目录 dir中提供了文件流,而walk*方法遍历子树的 包括子树的根目录 - 目录本身。

walkwalkFileTree之间的区别在于它们为树的行走提供了不同的界面:walkFileTree需要FileVisitorwalkStream<Path> }。

public class FilesTest {
    public static void main(String[] args) {
        final String pwd = System.getProperty("user.dir");
        System.out.println("Working Directory = " + pwd);
        Path dir = Paths.get(pwd);
        System.out.println("Files.walk");
        try {
            Files.walk(dir, 1).forEach(path -> FilesTest.doSomething("walk", path));
        } catch (IOException e) {
            logException("walk", e);
        }
        System.out.println("Files.walkFileTree");
        try {
            Files.walkFileTree(dir, Collections.emptySet(), 1, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    doSomething("visitFile", file);
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                    logException("visitFile", exc);
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException e) {
            logException("walkFileTree", e);
        }
        System.out.println("Files.list");
        try {
            Files.list(dir).forEach(path -> FilesTest.doSomething("dir", path));
        } catch (IOException e) {
            logException("dir", e);
        }
    }

    private static void logException(String title, IOException e) {
        System.err.println(title + "\terror: " + e);
    }

    private static void doSomething(String title, Path file) {
        System.out.println(title + "\t: " + file);
    }
}

答案 1 :(得分:1)

所有这3个解决方案看起来都是正确的,但最好使用最简单,最易读的方式,因此Files.list()看起来很自然,可以解决这个问题。

答案 2 :(得分:1)

Files.list 简单地委托给 Files.newDirectoryStream 并将底层 java.nio.file.DirectoryStream 公开为 java.util.stream.Stream,因此它们的功能基本相同,除了 Files.newDirectoryStream 允许您传递可选的 DirectoryStream.Filter

Files.walkFileTree 还公开了 BasicFileAttributes(例如 lastModifiedTimeisRegularFilesize)。如果您需要这些属性,从 Files.walkFileTree 获取它们可能更方便(也可能更有效),而不是单独查找。