4

If I have a directory contains a lot of files (about 1000 file). Some of these files named .processed and other not.

How can I list only 10 unprocessed files.

I am using this code to filter the processed file.

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

But if the number of un-processed files is huge, this may lead to memory error. so I need to read a limited number of files each time the application will run.

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
Fanooos
  • 2,718
  • 5
  • 31
  • 55

2 Answers2

13

Which is why you should use java.nio.file. Using 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());
}

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

Unlike File.listFiles(), java.nio.file use lazily populated streams of directory entries.

One more reason to ditch File. This is 2015 after all.

fge
  • 119,121
  • 33
  • 254
  • 329
4

In Java 8, you can directly use Files.walk() to create a Stream of Path:

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

In Java 7, you should not use DirectoryStream.Filter if you want that the files iteration stops as soon as the number of files to find is reached. You could create a SimpleFileVisitor implementation to achieve it.

Whatever the number of files, to achieve such a requirement : extracting a specific number of files matching to a predicate from a directory, using SimpleFileVisitor appear straighter and more efficient than DirectoryStream.Filter.
So I think that it should be favored.
See my answer in this duplicate to see how to implement it.

davidxxx
  • 125,838
  • 23
  • 214
  • 215