DirectoryStream iterates directory entries while holding an I/O resource. A bounded listing needs a close scope, an explicit maximum, and a policy for iteration failures.
Java DirectoryStream: close iteration and reject silent truncation
Operational contract
Unlike a materialized list, iteration can fail after some entries have already been seen. The caller must not confuse the partial result with a complete batch. The program selects manifest names, rejects a forty-eighth match, sorts the accepted names for stable reporting, and unwraps a DirectoryIteratorException as an I/O failure. Directory iteration order is not a business order. If a larger scan is required, design a chunked consumer or use a database-backed inventory instead of quietly dropping entries.
Failure case
A review job expects at most 47 staging manifests. Forty-seven matches fit; a forty-eighth is a capacity error, not the first file of an invisible next page. Sorting makes a report reproducible for the snapshot that was observed, but a producer can still change the directory during iteration. The job records the scan time and verifies each opened file again before processing.
Java code
import java.io.IOException;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class BoundedManifestListing {
public static List<Path> list(Path staging) throws IOException {
List<Path> matches = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(staging, "*.manifest")) {
for (Path candidate : stream) {
if (matches.size() == 47) throw new IOException("More than 47 manifests");
matches.add(candidate);
}
} catch (DirectoryIteratorException failure) {
throw new IOException("Manifest listing failed", failure.getCause());
}
matches.sort(Comparator.comparing(path -> path.getFileName().toString()));
return matches;
}
}Performance and ownership cost
The listing visits N entries and sorting M matches takes O(M log M) time with O(M) retained paths. The cap bounds M at 47 for this job. It does not bound the provider's traversal work or prove the directory stayed unchanged between listing and open.
Common Mistakes
- Do not leave DirectoryStream open after iteration.
- Do not assume iteration order is sorted.
- Do not return a partial list after an iteration failure or cap breach.
Connected lessons
- Java Files.walk: close the stream that owns directory handles
- Java walkFileTree: visit failures without hiding incomplete scans
- Java bounded line reader: reject oversized records without buffering the file
- Java WatchService: register, consume, and reset each key
- Java WatchService OVERFLOW: reconcile against directory state
- Java symbolic links: inspect attributes without claiming race safety
- Java file, JDBC, and subprocess boundaries quiz
- Advanced Java
