获取按上次修改排序的目录中的文件?

时间:2012-09-03 20:53:51

标签: java java-7

在Java 7中使用新的I / O API,是否有一种简单的方法可以按上次修改日期列出目录的内容?基本上我只需要获取最长时间未修改的文件(按上次修改升序排序,取第一个文件名)。

6 个答案:

答案 0 :(得分:21)

没有真正的“简单方法”,但有可能:

List<Path> files = new ArrayList<>();
try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
    for(Path p : stream) {
        files.add(p);
    }
}

Collections.sort(files, new Comparator<Path>() {
    public int compare(Path o1, Path o2) {
        try {
            return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2));
        } catch (IOException e) {
            // handle exception
        }
    }
});

这将最后修改最快修改文件的文件。 DirectoryStream不会遍历子目录。

答案 1 :(得分:6)

杰弗里答案的略微“流”变化,有些人可能会觉得更容易。发布完整性。

try (DirectoryStream<Path> files = Files.newDirectoryStream(path)) {
    StreamSupport.stream(files.spliterator(), false)
        .sorted((o1, o2) -> {
            try {
                return Files.getLastModifiedTime(o1).compareTo(Files.getLastModifiedTime(o2));
            } catch (IOException ex) {
                ...
            }
        })
        .filter(file -> Files.isRegularFile(file))
        .forEach(file -> {
        });
}

答案 2 :(得分:2)

在目录的File对象上使用listFiles()。将数组转换为arraylist。然后使用Customments类上的静态排序方法对它们进行排序,并使用自定义Comparator,该方法使用Files上的getTotalSpace()方法。 编辑:使用lastModified而不是getTotalSpace。

答案 3 :(得分:0)

lastModified()

返回上次修改此抽象路径名表示的文件的时间。

Java 7 - IO API

答案 4 :(得分:0)

您可以使用http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#listFiles(java.io.FileFilter)并提供http://docs.oracle.com/javase/1.5.0/docs/api/java/io/FileFilter.html

然后比较http://docs.oracle.com/javase/1.5.0/docs/api/java/io/File.html#lastModified(),你就完成了

如果你关心性能 - 那么只需从文件列表中选择一个具有最大/最小值的那个,这将给你O(n)复杂度

答案 5 :(得分:0)

注意:此解决方案需要Guava。

Java IO / NIO API为目录列表提供低级访问,但没有完成任何处理,而是留给调用者。 新的J ava7 NIO DirectoryStream 在访问目录列表以进行进一步处理时具有最小的占用空间,例如:排序

以下是我的解决方案:从 DirectoryStream 中读取文件,并从流中构建一个(可选)大小有限的排序队列。返回队列中最旧/最新的元素。

private void listFilesOldestFirst(final File directory, final Integer maxNumberOfFiles) {

    final Builder<File> builder =
            MinMaxPriorityQueue
            .orderedBy(LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
    if( maxNumberOfFiles != null ) {
        builder.maximumSize(maxNumberOfFiles);
    }

    // queue with constant space, if maxNumberOfFiles is set, otherwise behaves like an unbound queue with an O(log n) penalty for insertion
    final MinMaxPriorityQueue<File> oldestFiles = builder.create();

    try(DirectoryStream<Path> stream = Files.newDirectoryStream(directory.toPath())) {
        for(final Path p : stream) {
            oldestFiles.add(p.toFile());
        }
    } catch (final IOException e) {
        throw new RuntimeException(e);
    }

    final File[] fileArray = oldestFiles.toArray(new File[]{});
    Arrays.sort(fileArray, oldestFiles.comparator());
    // ... use fileArray

    final ArrayList<File> arrayList = Lists.newArrayList(oldestFiles);
    Collections.sort(arrayList, oldestFiles.comparator());
    // ... use arrayList

}

这些依赖关系是Guava MinMaxPriorityQueue FileComparator 所必需的:

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>

您还可以找到 Files.newDirectoryStream 过滤器参数:

    final Filter<Path> sampleFilter = new Filter<Path>() {
        @Override
        public boolean accept(final Path entry) throws IOException {
            return true; // see commons-io -> FileFilterUtils
        }
    };

    ...
    Files.newDirectoryStream(directory.toPath(), sampleFilter)