java - 用于列出基于特定日期/时间的文件的 DirectoryStream.Filter 示例

标签 java file-io nio2

我正在尝试研究 newDirectoryStreamDirecoryStream.Filter 示例,我可以在其中列出目录下的所有文件(及其所有子目录) 超过 60 天,例如。

DirectoryStream<Path> dirS = Files.newDirectoryStream(Paths.get("C:/myRootDirectory"), <DirectoryStream.filter>);

for (Path entry: dirS) {
    System.out.println(entry.toString());
}

在上面的代码中,DirectoryStream.filter 应该是什么?
这将是一个很大的帮助,因为我在一个项目中,我试图删除早于某个时间戳的文件,而 Java 1.7 之前的 File.listFiles() 只是挂起。

Files.walkFileTree() 可以提供一个选项吗?

最佳答案

如果我做对了,你有两种情况:

  1. 创建自定义过滤器以选择超过 60 天的文件
  2. 遍历子目录(整个 FileTree)并收集您的信息

使用 Calendar 类实现的 60 天条件更易于实现自定义过滤器:

DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
    @Override
    public boolean accept(Path entry) throws IOException {BasicFileAttributes attr = Files.readAttributes(entry,BasicFileAttributes.class);
    FileTime creationTime = attr.creationTime();
    Calendar cal = Calendar.getInstance();
    int days = cal.fieldDifference(new Date(creationTime.toMillis()),Calendar.DAY_OF_YEAR);
        return (Math.abs(days) > 60);
        }
  };

正常执行只会查找根目录下的文件。要查找子目录,您对使用 walkFileTree() 的猜测是正确的。

但是,这需要实现 FileVisitor 接口(interface),幸运的是,它的一个简单实现与 7 - SimpleFileVisitor 捆绑在一起。

要遍历子目录,您可以选择覆盖目录特定方法 - 我在这里使用了 SimpleFileVisitorpreVisitDirectory:

Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path file,
                    BasicFileAttributes attrs) {

由于 preVisitDirectory 将被定制为 return FileVisitResult.CONTINUE; 如果您没有任何额外的限制,我们将利用 preVisitDirectory 在应用过滤器时一次遍历目录 1 的方法。

Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path file,
                    BasicFileAttributes attrs) {

                DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
                    @Override
                    public boolean accept(Path entry) throws IOException {
                        BasicFileAttributes attr = Files.readAttributes(entry,
                                BasicFileAttributes.class);
                        FileTime creationTime = attr.creationTime();
                        Calendar cal = Calendar.getInstance();
                        int days = cal.fieldDifference(
                                new Date(creationTime.toMillis()),
                                Calendar.DAY_OF_YEAR);
                        return (Math.abs(days) > 60);
                    }
                };
                try (DirectoryStream<Path> stream = Files.newDirectoryStream(
                        file, filter)) {
                    for (Path path : stream) {
                        System.out.println(path.toString());
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                return FileVisitResult.CONTINUE;

            }
        }); 

这将为您提供所需过滤条件的整个目录和子目录结构中的文件,下面是完整的主要方法:

public static void main(String[] args) throws IOException {
        Path dirs = Paths.get("C:/");

        Files.walkFileTree(dirs, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path file,
                    BasicFileAttributes attrs) {

                DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
                    @Override
                    public boolean accept(Path entry) throws IOException {
                        BasicFileAttributes attr = Files.readAttributes(entry,
                                BasicFileAttributes.class);
                        FileTime creationTime = attr.creationTime();
                        Calendar cal = Calendar.getInstance();
                        int days = cal.fieldDifference(
                                new Date(creationTime.toMillis()),
                                Calendar.DAY_OF_YEAR);
                        return (Math.abs(days) > 60);
                    }
                };
                try (DirectoryStream<Path> stream = Files.newDirectoryStream(
                        file, filter)) {
                    for (Path path : stream) {
                        System.out.println(path.toString());
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                return FileVisitResult.CONTINUE;

            }
        });

    }

关于java - 用于列出基于特定日期/时间的文件的 DirectoryStream.Filter 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21733390/

相关文章:

java - 查询文档中的子子标签

java - 在 Android 中编辑现有文件

java - 在列表中查找扩展特定类的对象

java - 在使用c3p0连接池配置的Mysql主从复制中偶尔会遇到到slave的通信链路故障

java - 为什么我的程序无法识别文本文件中的所有名称?

python-3.x - 使用 Python 将日文字符输出到文件

java - 如何检查 java.nio.file.Path 是否来自默认文件系统?

java - 如何使用 AsynchronousServerSocketChannel 绑定(bind)多个端口?

java - Files.list 和 Files.walkFileTree 和 Files.walk with maxdepth = 1 有什么区别?

java - mysql更新查询中的自动增量