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

时间:2014-02-12 16:13:39

标签: java file-io nio2

我正在尝试调查DirecoryStream.Filter的{​​{1}}示例,我可以在其中列出早于目录的所有文件(及其所有子目录)以60天为例。

newDirectoryStream

在上面的代码中,DirectoryStream<Path> dirS = Files.newDirectoryStream(Paths.get("C:/myRootDirectory"), <DirectoryStream.filter>); for (Path entry: dirS) { System.out.println(entry.toString()); } 应该是什么?
这将是一个很好的帮助,因为我在一个项目中,我试图删除早于某个时间戳的文件,并且java-{1.7}之前的文件只是挂起。

可以DirectoryStream.filter提供选项吗?

2 个答案:

答案 0 :(得分:7)

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

  1. 创建自定义filter以选择超过60天的文件
  2. 遍历子目录(整个FileTree)并收集您的信息
  3. 使用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接口,这是一个简单的实现,幸运的是与7 - SimpleFileVisitor捆绑在一起。

    要遍历子目录,您可以选择覆盖特定于目录的方法 - 我在preVisitDirectory使用了SimpleFileVisitor

    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;
    
                }
            });
    
        }
    

答案 1 :(得分:3)

如果给定的DirectoryStream.Filter对象超过60天,只需创建一个返回true的新Path实例。

DirectoryStream<Path> dirStream = Files.newDirectoryStream(Paths.get("/some/path"), new Filter<Path>() {
    @Override
    public boolean accept(Path entry) throws IOException {
        FileTime fileTime = Files.getLastModifiedTime(entry);
        long millis = fileTime.to(TimeUnit.MILLISECONDS);
        Calendar today = Calendar.getInstance();
        // L is necessary for the result to correctly be calculated as a long 
        return today.getTimeInMillis() > millis + (60L * 24 * 60 * 60 * 1000);
    }
});

请注意,这只会为您提供指定目录Path的根目录内的文件,即。 Path参数传递给newDirectoryStream(..)

如果您想要子目录中的所有文件,Files.walkFileTree(..)可能更容易使用。您只需要实现一个FileVisitor,它使用与{{1}相同的逻辑存储您在此过程中收集的ListSetPath个对象上面。