Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do terminal operations on streams close the source? [duplicate]

Tags:

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?

like image 774
skiwi Avatar asked Dec 09 '14 14:12

skiwi


People also ask

What is true of terminal stream operations?

A terminal stream operation is an operation that starts the internal iteration of the elements, calls all the listeners, and returns a result. The call to the map() method of the Stream interface is a non-terminal operation. It merely sets a lambda expression on the stream which converts each element to lowercase.

What is terminal operation in stream API?

The Java Stream API's terminal operations return the final result of iterating through all the elements in the stream, and providing the non-terminal and terminal operations to the elements. The result of the terminal operation is returned after the last element in the stream has been processed.

When performing operations on stream it will affect the original stream?

A stream can be composed of multiple functions that create a pipeline that data that flows through. This data cannot be mutated. That is to say the original data structure doesn't change. However the data can be transformed and later stored in another data structure or perhaps consumed by another operation.


1 Answers

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.

like image 135
David ten Hove Avatar answered Oct 12 '22 16:10

David ten Hove