【问题标题】:How to list only N files in directory using java如何使用java仅列出目录中的N个文件
【发布时间】:2015-02-24 11:42:49
【问题描述】:

如果我有一个目录包含很多文件(大约 1000 个文件)。其中一些文件名为 .processed,而另一些则不是。

我怎样才能只列出 10 个未处理的文件。

我正在使用此代码过滤已处理的文件。

File[] inputFileList = inputDirectory.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return !pathname.getName().endsWith(".processed");
                }
            });

但是如果未处理的文件数量很大,这可能会导致内存错误。所以每次应用程序运行时我都需要读取有限数量的文件。

【问题讨论】:

    标签: java java-io


    【解决方案1】:

    这就是你应该使用 java.nio.file 的原因。使用 Java 8:

    final Path baseDir = Paths.get("path/to/dir");
    
    final List<Path> tenFirstEntries;
    
    final BiPredicate<Path, BasicFileAttributes> predicate = (path, attrs)
        -> attrs.isRegularFile() && path.getFileName().endsWith(".processed");
    
    try (
        final Stream<Path> stream = Files.find(baseDir, 1, predicate);
    ) {
        tenFirstEntries = stream.limit(10L).collect(Collectors.toList());
    }
    

    使用 Java 7:

    final Path baseDir = Paths.get("path/to/dir");
    
    final List<Path> tenFirstEntries = new ArrayList<>(10);
    
    final DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>()
    {
        @Override
        public boolean accept(final Path entry)
        {
            return entry.getFileName().endsWith(".processed")
                && Files.isRegularFile(entry);
        }
    };
    
    try (
        final DirectoryStream<Path> stream 
            = Files.newDirectoryStream(baseDir, filter);
    ) {
        final Iterator<Path> iterator = stream.iterator();
        for (int i = 0; iterator.hasNext() && i < 10; i++)
            tenFirstEntries.add(iterator.next());
    }
    

    File.listFiles() 不同,java.nio.file 使用延迟填充的目录条目流。

    放弃File 的另一个理由。毕竟这是 2015 年。

    【讨论】:

    • 请注意,路径的 endsWith() 与 String 的工作方式不同
    【解决方案2】:

    在Java 8中,可以直接使用Files.walk()创建StreamPath

    Path folder = Paths.get("...");
    final int nbFilesToFound = 10;
    List<Path> collect = Files.walk(folder)
                              .filter(p -> Files.isRegularFile(p) && !p.getFileName().toString().endsWith(".processed"))
                              .limit(nbFilesToFound)
                              .collect(Collectors.toList());
    

    在 Java 7 中,如果您希望文件迭代在达到要查找的文件数后立即停止,则不应使用 DirectoryStream.Filter。 您可以创建一个SimpleFileVisitor 实现来实现它。

    无论有多少文件,要实现这样的要求:从目录中提取与谓词匹配的特定数量的文件,使用SimpleFileVisitorDirectoryStream.Filter 看起来更直接和更有效。
    所以我认为它应该受到青睐。
    请参阅我在 this duplicate 中的回答,了解如何实现它。

    【讨论】:

    • 这是否限制将所有文件加载到内存中然后进行过滤?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    相关资源
    最近更新 更多