Consider the following code:
Path directory = Paths.get(/* some directory */);
Files.list(directory).forEach(System.out::println);
Does a terminal operation (like forEach
) close the underlying file that has been opened?
Refer to the relevant parts of the javadoc of Files.list:
The returned stream encapsulates a DirectoryStream. If timely disposal of file system resources is required, the try-with-resources construct should be used to ensure that the stream's close method is invoked after the stream operations are completed.
If it doesn't call Stream.close()
, what would then be the best alternative to call it while producing maintainable code?
Terminal operators do NOT close the stream automatically. Consider this code:
Stream<Path> list = Files.list(directory).onClose(() -> System.out.println("Closed"));
list.forEach(System.out::println);
This does NOT print "Closed".
However, the following does print "Closed":
try (Stream<Path> list = Files.list(directory).onClose(() -> System.out.println("Closed"))) {
list.forEach(System.out::println);
}
So the best way to do it is to use the try-with-resources mechanism.
In Java 9+, the resource can be declared and instantiated before the try
. See JEP 213.
Stream<Path> list = Files.list(directory).onClose(() -> System.out.println("Closed")) ;
…
try (list) {
list.forEach(System.out::println);
}